Skip to content

Commit

Permalink
Merge 380749f into bee6483
Browse files Browse the repository at this point in the history
  • Loading branch information
eh-am committed Feb 4, 2022
2 parents bee6483 + 380749f commit fafd229
Show file tree
Hide file tree
Showing 6 changed files with 200 additions and 31 deletions.
Binary file modified cypress/snapshots/e2e.ts/e2e-comparison-flamegraph-left.snap.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified cypress/snapshots/e2e.ts/e2e-comparison-flamegraph-right.snap.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified cypress/snapshots/e2e.ts/e2e-render-standalone.snap.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified cypress/snapshots/e2e.ts/e2e-single-flamegraph.snap.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
@@ -1,5 +1,9 @@
import Color from 'color';
import { colorBasedOnDiffPercent, NewDiffColor } from './color';
import {
colorBasedOnDiffPercent,
NewDiffColor,
getPackageNameFromStackTrace,
} from './color';
import { DefaultPalette } from './colorPalette';

describe.each([
Expand Down Expand Up @@ -37,3 +41,192 @@ describe('NewDiffColor with white-to-black example palette', () => {
});
});
});

describe('getPackageNameFromStackTrace', () => {
describe('golang', () => {
describe.each([
['bufio.(*Reader).fill', 'bufio.'],
['cmpbody', 'cmpbody'],
['bytes.Compare', 'bytes.'],
['crypto/tls.(*Conn).clientHandshake', 'crypto/tls.'],
[
'github.com/DataDog/zstd._Cfunc_ZSTD_compress_wrapper',
'github.com/DataDog/zstd.',
],
[
'github.com/dgraph-io/badger/v2.(*DB).calculateSize',
'github.com/dgraph-io/badger/v2.',
],
[
'github.com/dgraph-io/badger/v2/table.(*blockIterator).next',
'github.com/dgraph-io/badger/v2/table.',
],
['path/filepath.walk', 'path/filepath.'],
['os.(*File).write', 'os.'],
])(`.getPackageNameFromStackTrace('%s')`, (a, expected) => {
it(`returns '${expected}'`, () => {
expect(getPackageNameFromStackTrace('gospy', a)).toBe(expected);
});
});
});

describe('pyspy', () => {
describe.each([
['total', 'total'],
[
'System.Private.CoreLib!System.Threading.TimerQueue.FireNextTimers()',
'System.Private.CoreLib!System.Threading',
],
[
'StackExchange.Redis!StackExchange.Redis.ConnectionMultiplexer.OnHeartbeat()',
'StackExchange.Redis!StackExchange.Redis',
],
[
'Microsoft.AspNetCore.Server.Kestrel.Core!Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpRequestPipeReader.ReadAsync(value class System.Threading.CancellationToken)',
'Microsoft.AspNetCore.Server.Kestrel.Core!Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http',
],
[
'Google.Protobuf!Google.Protobuf.ParsingPrimitivesMessages.ReadRawMessage(value class Google.Protobuf.ParseContext\u0026,class Google.Protobuf.IMessage)',
'Google.Protobuf!Google.Protobuf',
],
[
'Grpc.AspNetCore.Server!Grpc.AspNetCore.Server.Internal.PipeExtensions.ReadSingleMessageAsync(class System.IO.Pipelines.PipeReader,class Grpc.AspNetCore.Server.Internal.HttpContextServerCallContext,class System.Func`2\u003cclass Grpc.Core.DeserializationContext,!!0\u003e)',
'Grpc.AspNetCore.Server!Grpc.AspNetCore.Server.Internal',
],
[
'System.Private.CoreLib!System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1[System.__Canon].GetStateMachineBox(!!0\u0026,class System.Threading.Tasks.Task`1\u003c!0\u003e\u0026)',
'System.Private.CoreLib!System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1[System',
],
])(`.getPackageNameFromStackTrace('%s')`, (a, expected) => {
it(`returns '${expected}'`, () => {
expect(getPackageNameFromStackTrace('dotnetspy', a)).toBe(expected);
});
});
});

describe('pyspy', () => {
describe.each([
['total', 'total'],
['urllib3/response.py:579 - stream', 'urllib3/'],
['requests/models.py:580 - prepare_cookies', 'requests/'],
['logging/__init__.py:1548 - findCaller', 'logging/'],
[
'jaeger_client/thrift_gen/jaeger/ttypes.py:147 - write',
'jaeger_client/thrift_gen/jaeger/',
],

// TODO: this one looks incorrect, but keeping in the test for now
[
'\u003cfrozen importlib._bootstrap\u003e:1030 - _gcd_import',
'<frozen importlib._bootstrap>:1030 - _gcd_import',
],
])(`.getPackageNameFromStackTrace('%s')`, (a, expected) => {
it(`returns '${expected}'`, () => {
expect(getPackageNameFromStackTrace('pyspy', a)).toBe(expected);
});
});
});

describe('rbspy', () => {
describe.each([
['total', 'total'],
['webrick/utils.rb:194 - watch', 'webrick/'],
['webrick/server.rb:190 - block (2 levels) in start', 'webrick/'],
[
'gems/sinatra-2.0.3/lib/sinatra/base.rb:1537 - start_server',
'gems/sinatra-2.0.3/lib/sinatra/',
],
['services/driver/client.rb:34 - get_drivers', 'services/driver/'],
['uri/common.rb:742 - URI', 'uri/'],
['net/protocol.rb:299 - block in write0', 'net/'],
])(`.getPackageNameFromStackTrace('%s')`, (a, expected) => {
it(`returns '${expected}'`, () => {
expect(getPackageNameFromStackTrace('rbspy', a)).toBe(expected);
});
});
});

describe('ebpfspy', () => {
describe.each([
['total', 'total'],
['entry_SYSCALL_64_after_hwframe', 'entry_SYSCALL_64_after_hwframe'],
['[unknown]', '[unknown]'],
[
'QApplicationPrivate::notify_helper(QObject*, QEvent*)',
'QApplicationPrivate::notify_helper(QObject*, QEvent*)',
],
[
'v8::internal::(anonymous namespace)::Invoke(v8::internal::Isolate*, v8::internal::(anonymous namespace)::InvokeParams const&)',
'v8::internal::(anonymous namespace)::Invoke(v8::internal::Isolate*, v8::internal::(anonymous namespace)::InvokeParams const&)',
],
[
'github.com/pyroscope-io/pyroscope/pkg/agent.(*ProfileSession).Start.dwrap.3',
'github.com/pyroscope-io/pyroscope/pkg/agent.(*ProfileSession).Start.dwrap.3',
],
])(`.getPackageNameFromStackTrace('%s')`, (a, expected) => {
it(`returns '${expected}'`, () => {
expect(getPackageNameFromStackTrace('ebpfspy', a)).toBe(expected);
});
});
});

describe('default', () => {
describe.each([
['total', 'total'],
['entry_SYSCALL_64_after_hwframe', 'entry_SYSCALL_64_after_hwframe'],
['[unknown]', '[unknown]'],
[
'QApplicationPrivate::notify_helper(QObject*, QEvent*)',
'QApplicationPrivate::notify_helper(QObject*, QEvent*)',
],
[
'v8::internal::(anonymous namespace)::Invoke(v8::internal::Isolate*, v8::internal::(anonymous namespace)::InvokeParams const&)',
'v8::internal::(anonymous namespace)::Invoke(v8::internal::Isolate*, v8::internal::(anonymous namespace)::InvokeParams const&)',
],
[
'github.com/pyroscope-io/pyroscope/pkg/agent.(*ProfileSession).Start.dwrap.3',
'github.com/pyroscope-io/pyroscope/pkg/agent.(*ProfileSession).Start.dwrap.3',
],
])(`.getPackageNameFromStackTrace('%s')`, (a, expected) => {
it(`returns '${expected}'`, () => {
expect(getPackageNameFromStackTrace('default', a)).toBe(expected);
});
});
});

describe('rust', () => {
describe.each([
['total', 'total'],
['std::thread::local::LocalKey<T>::with', 'std'],
[
'tokio::runtime::basic_scheduler::CoreGuard::block_on::{{closure}}::{{closure}}::{{closure}}',
'tokio',
],
[
'<core::future::from_generator::GenFuture<T> as core::future::future::Future>::poll',
'<core',
],
[
'reqwest::blocking::client::ClientHandle::new::{{closure}}::{{closure}}',
'reqwest',
],
['core::time::Duration::as_secs', 'core'],
['clock_gettime@GLIBC_2.2.5', 'clock_gettime@GLIBC_2.2.5'],
[
'hyper::proto::h1::dispatch::Dispatcher<D,Bs,I,T>::poll_catch debugger eval code',
'hyper',
],
['openssl::ssl::connector::SslConnector::builder', 'openssl'],

// TODO looks incorrect
[
'<F as futures_core::future::TryFuture>::try_poll',
'<F as futures_core',
],
])(`.getPackageNameFromStackTrace('%s')`, (a, expected) => {
it(`returns '${expected}'`, () => {
expect(getPackageNameFromStackTrace('pyroscope-rs', a)).toBe(expected);
});
});
});
});
@@ -1,37 +1,9 @@
/* eslint-disable camelcase */
import Color from 'color';
import { scaleThreshold, scaleLinear } from 'd3-scale';
import { scaleLinear } from 'd3-scale';
import murmurhash3_32_gc from './murmur3';
import type { FlamegraphPalette } from './colorPalette';

const colors = [
Color.hsl(24, 69, 60),
Color.hsl(34, 65, 65),
Color.hsl(194, 52, 61),
Color.hsl(163, 45, 55),
Color.hsl(211, 48, 60),
Color.hsl(246, 40, 65),
Color.hsl(305, 63, 79),
Color.hsl(47, 100, 73),

Color.rgb(183, 219, 171),
Color.rgb(244, 213, 152),
Color.rgb(112, 219, 237),
Color.rgb(249, 186, 143),
Color.rgb(242, 145, 145),
Color.rgb(130, 181, 216),
Color.rgb(229, 168, 226),
Color.rgb(174, 162, 224),
Color.rgb(154, 196, 138),
Color.rgb(242, 201, 109),
Color.rgb(101, 197, 219),
Color.rgb(249, 147, 78),
Color.rgb(234, 100, 96),
Color.rgb(81, 149, 206),
Color.rgb(214, 131, 206),
Color.rgb(128, 110, 183),
];

export const defaultColor = Color.rgb(148, 142, 142);
export const diffColorRed = Color.rgb(200, 0, 0);
export const diffColorGreen = Color.rgb(0, 170, 0);
Expand Down Expand Up @@ -106,14 +78,18 @@ export function getPackageNameFromStackTrace(
) {
// TODO: actually make sure these make sense and add tests
const regexpLookup = {
default: /^(?<packageName>(.*\/)*)(?<filename>.*)(?<line_info>.*)$/,
dotnetspy: /^(?<packageName>.+)\.(.+)\.(.+)\(.*\)$/,
// we don't have enough information
default: /^(?<packageName>.+)$/,
// TODO: come up with a clever heuristic
ebpfspy: /^(?<packageName>.+)$/,
// tested with pyroscope stacktraces here: https://regex101.com/r/99KReq/1
gospy: /^(?<packageName>.*?\/.*?\.|.*?\.|.+)(?<functionName>.*)$/,
phpspy: /^(?<packageName>(.*\/)*)(?<filename>.*\.php+)(?<line_info>.*)$/,
pyspy: /^(?<packageName>(.*\/)*)(?<filename>.*\.py+)(?<line_info>.*)$/,
rbspy: /^(?<packageName>(.*\/)*)(?<filename>.*\.rb+)(?<line_info>.*)$/,
'pyroscope-rs': /^(?<packageName>[^::]+)/,
// 'pyroscope-rs': /^(?<packageName>[a-zA-Z0-9]+)(::)?/,
};

if (stackTrace.length === 0) {
Expand Down

0 comments on commit fafd229

Please sign in to comment.