Group :: Monitoramento
RPM: flamegraph
Main Changelog Spec Patches Sources Download Gear Bugs e FR Repocop
Patch: flamegraph-1.0-alt.patch
Download
Download
.gear/flamegraph.spec | 64 +++++++++++++
.gear/rules | 3 +
.gear/tags/list | 1 +
dev/hcstackcollapse.pl | 2 +-
flamegraph.pl | 21 ++++-
stackcollapse-bpftrace.pl | 66 +++++++++++++
stackcollapse-go.pl | 2 +-
stackcollapse-java-exceptions.pl | 72 ++++++++++++++
stackcollapse-jstack.pl | 2 +-
stackcollapse-ljp.awk | 2 +-
stackcollapse-perf.pl | 2 +-
stackcollapse-stap.pl | 2 +-
stackcollapse-xdebug.php | 197 +++++++++++++++++++++++++++++++++++++++
stackcollapse.pl | 2 +-
14 files changed, 428 insertions(+), 10 deletions(-)
diff --git a/.gear/flamegraph.spec b/.gear/flamegraph.spec
new file mode 100644
index 0000000..17538d0
--- /dev/null
+++ b/.gear/flamegraph.spec
@@ -0,0 +1,64 @@
+Name: flamegraph
+Version: 1.0
+Release: alt2
+Epoch: 1
+
+Summary: Flame Graphs visualize profiled code-paths
+License: CDDL1.0/GPLv2+
+Group: Monitoring
+URL: http://www.brendangregg.com/flamegraphs.html
+
+BuildArch: noarch
+
+Source0: %name-%version.tar
+Patch0: %name-%version-alt.patch
+
+Conflicts: perl-Devel-NYTProf
+
+
+%description
+Flame Graphs visualize profiled code-paths.
+
+%prep
+%setup
+%patch0 -p1
+
+%install
+mkdir -p %buildroot%_bindir
+for file in *.pl *.awk dev/*.pl ;do
+install -p -m755 $file %buildroot%_bindir/
+done
+
+%files
+%_bindir/*
+%doc README.md example* demos dev/README
+
+%changelog
+* Fri Jan 11 2019 Terechkov Evgenii <evg@altlinux.org> 1:1.0-alt2
+- v1.0-13-gf857ebc
+- Add Conflicts: to perl-Devel-NYTProf (thanks, repocop)
+
+* Thu Sep 27 2018 Terechkov Evgenii <evg@altlinux.org> 1:1.0-alt1
+- v1.0-5-g18c3dea
+- Epoch tag added to proper package upgrade
+
+* Wed Aug 2 2017 Terechkov Evgenii <evg@altlinux.org> 20170801-alt1
+- git-20170801 (99972c0)
+
+* Wed Feb 8 2017 Terechkov Evgenii <evg@altlinux.org> 20170208-alt1
+- git-20170208 (54b5f97)
+
+* Thu Jan 28 2016 Terechkov Evgenii <evg@altlinux.org> 20160128-alt1
+- git-20160128
+
+* Sat Nov 14 2015 Terechkov Evgenii <evg@altlinux.org> 20151114-alt1
+- git-20151114
+
+* Tue Sep 15 2015 Terechkov Evgenii <evg@altlinux.org> 20150915-alt1
+- git-20150915
+
+* Sun Aug 16 2015 Terechkov Evgenii <evg@altlinux.org> 20150816-alt1
+- git-20150816
+
+* Mon Jul 13 2015 Terechkov Evgenii <evg@altlinux.org> 20150713-alt1
+- git-20150713
diff --git a/.gear/rules b/.gear/rules
new file mode 100644
index 0000000..c93dd65
--- /dev/null
+++ b/.gear/rules
@@ -0,0 +1,3 @@
+tar: v@version@:. name=@name@-@version@
+diff: v@version@:. . name=@name@-@version@-alt.patch
+spec: .gear/flamegraph.spec
diff --git a/.gear/tags/list b/.gear/tags/list
new file mode 100644
index 0000000..5d71e48
--- /dev/null
+++ b/.gear/tags/list
@@ -0,0 +1 @@
+a8d807a11c0f22871134324bda709618ca482b58 v1.0
diff --git a/dev/hcstackcollapse.pl b/dev/hcstackcollapse.pl
index cc249d0..9e56282 100755
--- a/dev/hcstackcollapse.pl
+++ b/dev/hcstackcollapse.pl
@@ -1,6 +1,6 @@
#!/usr/bin/perl -w
#
-# hcstackcolllapse.pl collapse hot/cold multiline stacks into single lines.
+# hcstackcollapse.pl collapse hot/cold multiline stacks into single lines.
#
# EXPERIMENTAL: This is a work in progress, and may not work properly.
#
diff --git a/flamegraph.pl b/flamegraph.pl
index 4723421..410700d 100755
--- a/flamegraph.pl
+++ b/flamegraph.pl
@@ -118,6 +118,7 @@ my %palette_map; # palette map hash
my $pal_file = "palette.map"; # palette map file name
my $stackreverse = 0; # reverse stack order, switching merge end
my $inverted = 0; # icicle graph
+my $flamechart = 0; # produce a flame chart (sort by time, do not merge stacks)
my $negate = 0; # switch differential hues
my $titletext = ""; # centered heading
my $titledefault = "Flame Graph"; # overwritten by --title
@@ -146,6 +147,7 @@ USAGE: $0 [options] infile > outfile.svg\n
--cp # use consistent palette (palette.map)
--reverse # generate stack-reversed flame graph
--inverted # icicle graph
+ --flamechart # produce a flame chart (sort by time, do not merge stacks)
--negate # switch differential hues (blue<->red)
--notes TEXT # add notes comment in SVG (for debugging)
--help # this message
@@ -175,6 +177,7 @@ GetOptions(
'cp' => \$palette,
'reverse' => \$stackreverse,
'inverted' => \$inverted,
+ 'flamechart' => \$flamechart,
'negate' => \$negate,
'notes=s' => \$notestext,
'help' => \$help,
@@ -191,6 +194,10 @@ my $depthmax = 0;
my %Events;
my %nameattr;
+if ($flamechart && $titletext eq "") {
+ $titletext = "Flame Chart";
+}
+
if ($titletext eq "") {
unless ($inverted) {
$titletext = $titledefault;
@@ -379,10 +386,10 @@ sub color {
$type = "aqua";
} elsif ($name =~ m:^L?(java|org|com|io|sun)/:) { # Java
$type = "green";
- } elsif ($name =~ /::/) { # C++
- $type = "yellow";
} elsif ($name =~ m:_\[k\]$:) { # kernel annotation
$type = "orange";
+ } elsif ($name =~ /::/) { # C++
+ $type = "yellow";
} else { # system
$type = "red";
}
@@ -564,6 +571,7 @@ sub flow {
# parse input
my @Data;
+my @SortedData;
my $last = [];
my $time = 0;
my $delta = undef;
@@ -592,8 +600,15 @@ foreach (<>) {
}
}
+if ($flamechart) {
+ # In flame chart mode, just reverse the data so time moves from left to right.
+ @SortedData = reverse @Data;
+} else {
+ @SortedData = sort @Data;
+}
+
# process and merge frames
-foreach (sort @Data) {
+foreach (@SortedData) {
chomp;
# process: folded_stack count
# eg: func_a;func_b;func_c 31
diff --git a/stackcollapse-bpftrace.pl b/stackcollapse-bpftrace.pl
new file mode 100755
index 0000000..e5d32a5
--- /dev/null
+++ b/stackcollapse-bpftrace.pl
@@ -0,0 +1,66 @@
+#!/usr/bin/perl -w
+#
+# stackcollapse-bpftrace.pl collapse bpftrace samples into single lines.
+#
+# USAGE ./stackcollapse-bpftrace.pl infile > outfile
+#
+# Example input:
+#
+# @[
+# _raw_spin_lock_bh+0
+# tcp_recvmsg+808
+# inet_recvmsg+81
+# sock_recvmsg+67
+# sock_read_iter+144
+# new_sync_read+228
+# __vfs_read+41
+# vfs_read+142
+# sys_read+85
+# do_syscall_64+115
+# entry_SYSCALL_64_after_hwframe+61
+# ]: 3
+#
+# Example output:
+#
+# entry_SYSCALL_64_after_hwframe+61;do_syscall_64+115;sys_read+85;vfs_read+142;__vfs_read+41;new_sync_read+228;sock_read_iter+144;sock_recvmsg+67;inet_recvmsg+81;tcp_recvmsg+808;_raw_spin_lock_bh+0 3
+#
+# Copyright 2018 Peter Sanford. All rights reserved.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# (http://www.gnu.org/copyleft/gpl.html)
+#
+
+use strict;
+
+my @stack;
+my $in_stack = 0;
+
+foreach (<>) {
+ chomp;
+ if (!$in_stack) {
+ if (/^@\[/) {
+ $in_stack = 1;
+ }
+ } else {
+ if (m/^\]: (\d+)/) {
+ print join(';', reverse(@stack)) . " $1\n";
+ $in_stack = 0;
+ @stack = ();
+ } else {
+ push(@stack, $_);
+ }
+ }
+}
diff --git a/stackcollapse-go.pl b/stackcollapse-go.pl
index 986b7d5..3b2ce3c 100755
--- a/stackcollapse-go.pl
+++ b/stackcollapse-go.pl
@@ -1,6 +1,6 @@
#!/usr/bin/perl -w
#
-# stackcolllapse-go.pl collapse golang samples into single lines.
+# stackcollapse-go.pl collapse golang samples into single lines.
#
# Parses golang smaples generated by "go tool pprof" and outputs stacks as
# single lines, with methods separated by semicolons, and then a space and an
diff --git a/stackcollapse-java-exceptions.pl b/stackcollapse-java-exceptions.pl
new file mode 100755
index 0000000..19badbc
--- /dev/null
+++ b/stackcollapse-java-exceptions.pl
@@ -0,0 +1,72 @@
+#!/usr/bin/perl -w
+#
+# stackcolllapse-java-exceptions.pl collapse java exceptions (found in logs) into single lines.
+#
+# Parses Java error stacks found in a log file and outputs them as
+# single lines, with methods separated by semicolons, and then a space and an
+# occurrence count. Inspired by stackcollapse-jstack.pl except that it does
+# not act as a performance profiler.
+#
+# It can be useful if a Java process dumps a lot of different stacks in its logs
+# and you want to quickly identify the biggest culprits.
+#
+# USAGE: ./stackcollapse-java-exceptions.pl infile > outfile
+#
+# Copyright 2018 Paul de Verdiere. All rights reserved.
+
+use strict;
+use Getopt::Long;
+
+# tunables
+my $shorten_pkgs = 0; # shorten package names
+my $no_pkgs = 0; # really shorten package names!!
+my $help = 0;
+
+sub usage {
+ die <<USAGE_END;
+USAGE: $0 [options] infile > outfile\n
+ --shorten-pkgs : shorten package names
+ --no-pkgs : suppress package names (makes SVG much more readable)
+
+USAGE_END
+}
+
+GetOptions(
+ 'shorten-pkgs!' => \$shorten_pkgs,
+ 'no-pkgs!' => \$no_pkgs,
+ 'help' => \$help,
+) or usage();
+$help && usage();
+
+my %collapsed;
+
+sub remember_stack {
+ my ($stack, $count) = @_;
+ $collapsed{$stack} += $count;
+}
+
+my @stack;
+
+foreach (<>) {
+ chomp;
+
+ if (/^\s*at ([^\(]*)/) {
+ my $func = $1;
+ if ($shorten_pkgs || $no_pkgs) {
+ my ($pkgs, $clsFunc) = ( $func =~ m/(.*\.)([^.]+\.[^.]+)$/ );
+ $pkgs =~ s/(\w)\w*/$1/g;
+ $func = $no_pkgs ? $clsFunc: $pkgs . $clsFunc;
+ }
+ unshift @stack, $func;
+ } elsif (@stack ) {
+ next if m/.*waiting on .*/;
+ remember_stack(join(";", @stack), 1) if @stack;
+ undef @stack;
+ }
+}
+
+remember_stack(join(";", @stack), 1) if @stack;
+
+foreach my $k (sort { $a cmp $b } keys %collapsed) {
+ print "$k $collapsed{$k}\n";
+}
diff --git a/stackcollapse-jstack.pl b/stackcollapse-jstack.pl
index f4aa6a1..24541d0 100755
--- a/stackcollapse-jstack.pl
+++ b/stackcollapse-jstack.pl
@@ -1,6 +1,6 @@
#!/usr/bin/perl -w
#
-# stackcolllapse-jstack.pl collapse jstack samples into single lines.
+# stackcollapse-jstack.pl collapse jstack samples into single lines.
#
# Parses Java stacks generated by jstack(1) and outputs RUNNABLE stacks as
# single lines, with methods separated by semicolons, and then a space and an
diff --git a/stackcollapse-ljp.awk b/stackcollapse-ljp.awk
index d1465ba..59aaae3 100755
--- a/stackcollapse-ljp.awk
+++ b/stackcollapse-ljp.awk
@@ -1,6 +1,6 @@
#!/usr/bin/awk -f
#
-# stackcolllapse-ljp.awk collapse lightweight java profile reports
+# stackcollapse-ljp.awk collapse lightweight java profile reports
# into single lines stacks.
#
# Parses a list of multiline stacks generated by:
diff --git a/stackcollapse-perf.pl b/stackcollapse-perf.pl
index e91f7de..5cefa82 100755
--- a/stackcollapse-perf.pl
+++ b/stackcollapse-perf.pl
@@ -1,6 +1,6 @@
#!/usr/bin/perl -w
#
-# stackcolllapse-perf.pl collapse perf samples into single lines.
+# stackcollapse-perf.pl collapse perf samples into single lines.
#
# Parses a list of multiline stacks generated by "perf script", and
# outputs a semicolon separated stack followed by a space and a count.
diff --git a/stackcollapse-stap.pl b/stackcollapse-stap.pl
index b04aac4..bca4046 100755
--- a/stackcollapse-stap.pl
+++ b/stackcollapse-stap.pl
@@ -1,6 +1,6 @@
#!/usr/bin/perl -w
#
-# stackcolllapse-stap.pl collapse multiline SystemTap stacks
+# stackcollapse-stap.pl collapse multiline SystemTap stacks
# into single lines.
#
# Parses a multiline stack followed by a number on a separate line, and
diff --git a/stackcollapse-xdebug.php b/stackcollapse-xdebug.php
new file mode 100755
index 0000000..6548903
--- /dev/null
+++ b/stackcollapse-xdebug.php
@@ -0,0 +1,197 @@
+#!/usr/bin/php
+#
+# Copyright 2018 Miriam Lauter (lauter.miriam@gmail.com). All rights reserved.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# (http://www.gnu.org/copyleft/gpl.html)
+#
+# 13-Apr-2018 Miriam Lauter Created this.
+
+<?php
+ini_set('error_log', null);
+$optind = null;
+$args = getopt("htc", ["help"], $optind);
+if (isset($args['h']) || isset($args['help'])) {
+ usage();
+}
+
+function usage($exit = 0) {
+ echo <<<EOT
+stackcollapse-php.php collapse php function traces into single lines.
+
+Parses php samples generated by xdebug with xdebug.trace_format = 1
+and outputs stacks as single lines, with methods separated by semicolons,
+and then a space and an occurrence count. For use with flamegraph.pl.
+See https://github.com/brendangregg/FlameGraph.
+
+USAGE: ./stackcollapse-php.php [OPTIONS] infile > outfile
+ -h --help Show this message
+ -t Weight stack counts by duration using the time index in the trace (default)
+ -c Invocation counts only. Simply count stacks in the trace and sum duplicates, don't weight by duration.
+
+Example input:
+For more info on xdebug and generating traces see
+https://xdebug.org/docs/execution_trace.
+
+Version: 2.0.0RC4-dev
+TRACE START [2007-05-06 18:29:01]
+1 0 0 0.010870 114112 {main} 1 ../trace.php 0
+2 1 0 0.032009 114272 str_split 0 ../trace.php 8
+2 1 1 0.032073 116632
+2 2 0 0.033505 117424 ret_ord 1 ../trace.php 10
+3 3 0 0.033531 117584 ord 0 ../trace.php 5
+3 3 1 0.033551 117584
+...
+TRACE END [2007-05-06 18:29:01]
+
+Example output:
+
+- c
+{main};str_split 1
+{main};ret_ord;ord 6
+
+-t
+{main} 23381
+{main};str_split 64
+{main};ret_ord 215
+{main};ret_ord;ord 106
+
+EOT;
+
+ exit($exit);
+}
+
+function collapseStack(array $stack, string $func_name_key): string {
+ return implode(';', array_column($stack, $func_name_key));
+}
+
+function addCurrentStackToStacks(array $stack, float $dur, array &$stacks) {
+ $collapsed = implode(';', $stack);
+ $duration = SCALE_FACTOR * $dur;
+
+ if (array_key_exists($collapsed, $stacks)) {
+ $stacks[$collapsed] += $duration;
+ } else {
+ $stacks[$collapsed] = $duration;
+ }
+}
+
+function isEOTrace(string $l) {
+ $pattern = "/^(\\t|TRACE END)/";
+ return preg_match($pattern, $l);
+}
+
+$filename = $argv[$optind] ?? null;
+if ($filename === null) {
+ usage(1);
+}
+
+$do_time = !isset($args['c']);
+
+// First make sure our file is consistently formatted with only one \t delimiting each field
+$out = [];
+$retval = null;
+exec("sed -in 's/\t\+/\t/g' " . escapeshellarg($filename), $out, $retval);
+if ($retval !== 0) {
+ usage(1);
+}
+
+$handle = fopen($filename, 'r');
+
+if ($handle === false) {
+ echo "Unable to open $filename \n\n";
+ usage(1);
+}
+
+// Loop till we find TRACE START
+while ($l = fgets($handle)) {
+ if (strpos($l, "TRACE START") === 0) {
+ break;
+ }
+}
+
+const SCALE_FACTOR = 1000000;
+$stacks = [];
+$current_stack = [];
+$was_exit = false;
+$prev_start_time = 0;
+
+if ($do_time) {
+ // Weight counts by duration
+ // Xdebug trace time indices have 6 sigfigs of precision
+ // We have a perfect trace, but let's instead pretend that
+ // this was collected by sampling at 10^6 Hz
+ // then each millionth of a second this stack took to execute is 1 count
+ while ($l = fgets($handle)) {
+ if (isEOTrace($l)) {
+ break;
+ }
+
+ $parts = explode("\t", $l);
+ list($level, $fn_no, $is_exit, $time) = $parts;
+
+ if ($is_exit) {
+ if (empty($current_stack)) {
+ echo "[WARNING] Found function exit without corresponding entrance. Discarding line. Check your input.\n";
+ continue;
+ }
+
+ addCurrentStackToStacks($current_stack, $time - $prev_start_time, $stacks);
+ array_pop($current_stack);
+ } else {
+ $func_name = $parts[5];
+
+ if (!empty($current_stack)) {
+ addCurrentStackToStacks($current_stack, $time - $prev_start_time, $stacks);
+ }
+
+ $current_stack[] = $func_name;
+ }
+ $prev_start_time = $time;
+ }
+} else {
+ // Counts only
+ while ($l = fgets($handle)) {
+ if (isEOTrace($l)) {
+ break;
+ }
+
+ $parts = explode("\t", $l);
+ list($level, $fn_no, $is_exit) = $parts;
+
+ if ($is_exit === "1") {
+ if (!$was_exit) {
+ $collapsed = implode(";", $current_stack);
+ if (array_key_exists($collapsed, $stacks)) {
+ $stacks[$collapsed]++;
+ } else {
+ $stacks[$collapsed] = 1;
+ }
+ }
+
+ array_pop($current_stack);
+ $was_exit = true;
+ } else {
+ $func_name = $parts[5];
+ $current_stack[] = $func_name;
+ $was_exit = false;
+ }
+ }
+}
+
+foreach ($stacks as $stack => $count) {
+ echo "$stack $count\n";
+}
diff --git a/stackcollapse.pl b/stackcollapse.pl
index 17144bb..1e00c52 100755
--- a/stackcollapse.pl
+++ b/stackcollapse.pl
@@ -1,6 +1,6 @@
#!/usr/bin/perl -w
#
-# stackcolllapse.pl collapse multiline stacks into single lines.
+# stackcollapse.pl collapse multiline stacks into single lines.
#
# Parses a multiline stack followed by a number on a separate line, and
# outputs a semicolon separated stack followed by a space and the number.