Skip to content
This repository has been archived by the owner on Jul 19, 2023. It is now read-only.

Introduce symdb #767

Merged
merged 48 commits into from
Jun 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
813ac6a
Increase parquet writer PageBufferSize
cyriltovena Jun 2, 2023
97eb8c5
reduce by 2 page buffer size
cyriltovena Jun 5, 2023
5b33929
Introduce symdb
kolesnikovae Jun 14, 2023
046e825
Add chunk format description
kolesnikovae Jun 14, 2023
bacbe04
Add chunk format description
kolesnikovae Jun 14, 2023
1c96cd5
Improve naming
kolesnikovae Jun 14, 2023
a967b21
Implement stack trace appender
kolesnikovae Jun 14, 2023
b380330
Limit chunk by number of nodes
kolesnikovae Jun 15, 2023
b108bac
Stacktrace ID is uint32
kolesnikovae Jun 15, 2023
401c00f
Add in-memory stacktrace resolver
kolesnikovae Jun 15, 2023
25bce59
Add writer
kolesnikovae Jun 15, 2023
6bba758
Add writer
kolesnikovae Jun 16, 2023
ddab48e
Fix stacktrace resolver
kolesnikovae Jun 16, 2023
71a9ee1
Single pass write
kolesnikovae Jun 16, 2023
b48d915
Index file refactoring
kolesnikovae Jun 16, 2023
42c607d
Fixes, improvements, notes
kolesnikovae Jun 16, 2023
9ce0a86
Ignore empty stacktraces
kolesnikovae Jun 16, 2023
38d1e0b
Fix chunk boundary check
kolesnikovae Jun 16, 2023
0240f17
Fix tests
kolesnikovae Jun 17, 2023
c7892a6
Store chunk headers sorted
kolesnikovae Jun 17, 2023
58cbafc
Make chunk index explicit
kolesnikovae Jun 17, 2023
da00cc0
Add file reader
kolesnikovae Jun 17, 2023
44fa701
Use group varint encoding
kolesnikovae Jun 18, 2023
845d559
Refine stacktrace tree
kolesnikovae Jun 20, 2023
2d5abc0
Stacktrace tree race condition elimination
kolesnikovae Jun 20, 2023
1271212
Remove unused stacktracesResolve.do
kolesnikovae Jun 20, 2023
8fb9a64
Better nil coalescence in stack trace appender
kolesnikovae Jun 20, 2023
5a349f8
Format imports
kolesnikovae Jun 20, 2023
e783311
Use the new symDB package (#770)
cyriltovena Jun 20, 2023
146866b
Merge remote-tracking branch 'origin/main' into feat/symdb
cyriltovena Jun 20, 2023
fcf5b8b
Use prefixed bucket for symbols
kolesnikovae Jun 20, 2023
dc8f2a1
Initialize locationsIdsByStacktraceID
kolesnikovae Jun 20, 2023
5701177
Initialize locationsIdsByStacktraceID for pprof as well
kolesnikovae Jun 20, 2023
a7e5597
Fix chunk headers sort
kolesnikovae Jun 21, 2023
6568873
Inline node alloc
kolesnikovae Jun 21, 2023
36922e7
Mapping filename extraction
kolesnikovae Jun 21, 2023
902ec0c
Tidy go.mod
kolesnikovae Jun 21, 2023
6757ee1
Fix TestHeadIngestStacktraces
kolesnikovae Jun 21, 2023
0acb4de
Use symdb.DefaultDirName
kolesnikovae Jun 22, 2023
2f5753b
Sort mappings on write
kolesnikovae Jun 22, 2023
10d1dbf
Make column iterator to respect the context
kolesnikovae Jun 22, 2023
825235c
Fix unexpected EOF on stacktrace chunk unmarshal
kolesnikovae Jun 22, 2023
c31f93d
Fix symbols upload
kolesnikovae Jun 22, 2023
20a815e
Fix symbols upload
kolesnikovae Jun 22, 2023
9241faa
Release fetched data
kolesnikovae Jun 22, 2023
03dc721
Merge branch 'experiment-page-size' into feat/symdb
cyriltovena Jun 26, 2023
4d7eb65
3MB Page Buffer Size
cyriltovena Jun 26, 2023
819f6e9
Sort stacktraces IDs as expected by the resolver
cyriltovena Jun 26, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ require (
github.com/bufbuild/connect-grpchealth-go v1.0.0
github.com/cespare/xxhash/v2 v2.2.0
github.com/dennwc/varint v1.0.0
github.com/dgryski/go-groupvarint v0.0.0-20211110171037-f5865eef0641
github.com/drone/envsubst v1.0.3
github.com/dustin/go-humanize v1.0.0
github.com/felixge/fgprof v0.9.4-0.20221116204635-ececf7638e93
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -571,6 +571,8 @@ github.com/dgraph-io/ristretto v0.1.1 h1:6CWw5tJNgpegArSHpNHJKldNeq03FQCwYvfMVWa
github.com/dgraph-io/ristretto v0.1.1/go.mod h1:S1GPSBCYCIhmVNfcth17y2zZtQT6wzkzgwUve0VDWWA=
github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2 h1:tdlZCpZ/P9DhczCTSixgIKmwPv6+wP5DGjqLYw5SUiA=
github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw=
github.com/dgryski/go-groupvarint v0.0.0-20211110171037-f5865eef0641 h1:z0nAHq7J9u9XvP/iyxka0dG6vGobRH5dAz38APXRCKo=
github.com/dgryski/go-groupvarint v0.0.0-20211110171037-f5865eef0641/go.mod h1:MlkUQveSLEDbIgq2r1e++tSf0zfzU9mQpa9Qkczl+9Y=
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
github.com/digitalocean/godo v1.98.0 h1:potyC1eD0N9n5/P4/WmJuKgg+OGYZOBWEW+/aKTX6QQ=
Expand Down
43 changes: 43 additions & 0 deletions pkg/model/profile.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
package model

import (
"path/filepath"
"strings"

"github.com/cespare/xxhash/v2"
"github.com/gogo/status"
"github.com/google/pprof/profile"
"github.com/prometheus/prometheus/model/labels"
"google.golang.org/grpc/codes"

profilev1 "github.com/grafana/phlare/api/gen/proto/go/google/v1"
ingestv1 "github.com/grafana/phlare/api/gen/proto/go/ingester/v1"
typesv1 "github.com/grafana/phlare/api/gen/proto/go/types/v1"
)
Expand Down Expand Up @@ -61,3 +64,43 @@ func SetProfileMetadata(p *profile.Profile, ty *typesv1.ProfileType) {
p.Period = 1
}
}

func StacktracePartitionFromProfile(lbls []Labels, p *profilev1.Profile) uint64 {
return xxhash.Sum64String(stacktracePartitionKeyFromProfile(lbls, p))
}

func stacktracePartitionKeyFromProfile(lbls []Labels, p *profilev1.Profile) string {
// take the first mapping (which is the main binary's file basename)
if len(p.Mapping) > 0 {
if filenameID := p.Mapping[0].Filename; filenameID > 0 {
if filename := extractMappingFilename(p.StringTable[filenameID]); filename != "" {
return filename
}
}
}

// failing that look through the labels for the ServiceName
if len(lbls) > 0 {
for _, lbl := range lbls[0] {
if lbl.Name == LabelNameServiceName {
return lbl.Value
}
}
}

return "unknown"
}

func extractMappingFilename(filename string) string {
// See github.com/google/pprof/profile/profile.go
// It's unlikely that the main binary mapping is one of them.
if filename == "" ||
strings.HasPrefix(filename, "[") ||
strings.HasPrefix(filename, "linux-vdso") ||
strings.HasPrefix(filename, "/dev/dri/") {
return ""
}
// Like filepath.ToSlash but doesn't rely on OS.
n := strings.ReplaceAll(filename, `\`, `/`)
return strings.TrimSpace(filepath.Base(filepath.Clean(n)))
}
36 changes: 36 additions & 0 deletions pkg/model/profile_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package model

import (
"testing"

"github.com/stretchr/testify/assert"
)

func Test_filename_extraction(t *testing.T) {
assert.Equal(t, "app", extractMappingFilename(`app`))
assert.Equal(t, "app", extractMappingFilename(`./app`))
assert.Equal(t, "app", extractMappingFilename(`/usr/bin/app`))
assert.Equal(t, "app", extractMappingFilename(`../../../app`))
assert.Equal(t, "app", extractMappingFilename(`/usr/bin/app\`))
assert.Equal(t, "app", extractMappingFilename(`/usr/bin/app\\`))
assert.Equal(t, "my awesome app", extractMappingFilename(`/usr/bin/my awesome app`))
assert.Equal(t, "app", extractMappingFilename(`/usr/bin/my\ awesome\ app`))

assert.Equal(t, "app.exe", extractMappingFilename(`C:\\app.exe`))
assert.Equal(t, "app.exe", extractMappingFilename(`C:\\./app.exe`))
assert.Equal(t, "app.exe", extractMappingFilename(`./app.exe`))
assert.Equal(t, "app.exe", extractMappingFilename(`./../app.exe`))
assert.Equal(t, "app.exe", extractMappingFilename(`C:\\build\app.exe`))
assert.Equal(t, "My App.exe", extractMappingFilename(`C:\\build\My App.exe`))
assert.Equal(t, "Not My App.exe", extractMappingFilename(`C:\\build\Not My App.exe`))
assert.Equal(t, "app.exe", extractMappingFilename(`\\app.exe`))
assert.Equal(t, "app.exe", extractMappingFilename(`\\build\app.exe`))

assert.Equal(t, "bin", extractMappingFilename(`/usr/bin/`))
assert.Equal(t, "build", extractMappingFilename(`\\build\`))

assert.Equal(t, "", extractMappingFilename(""))
assert.Equal(t, "", extractMappingFilename(`[vdso]`))
assert.Equal(t, "", extractMappingFilename(`[vsyscall]`))
assert.Equal(t, "not a path actually", extractMappingFilename(`not a path actually`))
}
14 changes: 10 additions & 4 deletions pkg/phlaredb/block/metadata.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ type MetaVersion int
const (
// Version1 is a enumeration of Phlare section of TSDB meta supported by Phlare.
MetaVersion1 = MetaVersion(1)
MetaVersion2 = MetaVersion(2)
)

type BlockStats struct {
Expand Down Expand Up @@ -130,6 +131,7 @@ func NewMeta() *Meta {
MinTime: math.MaxInt64,
MaxTime: 0,
Labels: make(map[string]string),
Version: MetaVersion2,
}
}

Expand All @@ -143,7 +145,10 @@ func MetaFromDir(dir string) (*Meta, int64, error) {
if err := json.Unmarshal(b, &m); err != nil {
return nil, 0, err
}
if m.Version != MetaVersion1 {
switch m.Version {
case MetaVersion1:
case MetaVersion2:
default:
return nil, 0, errors.Errorf("unexpected meta file version %d", m.Version)
}

Expand Down Expand Up @@ -174,8 +179,6 @@ func (meta *Meta) WriteTo(w io.Writer) (int64, error) {
}

func (meta *Meta) WriteToFile(logger log.Logger, dir string) (int64, error) {
meta.Version = MetaVersion1

// Make any changes to the file appear atomic.
path := filepath.Join(dir, MetaFilename)
tmp := path + ".tmp"
Expand Down Expand Up @@ -249,7 +252,10 @@ func Read(rc io.ReadCloser) (_ *Meta, err error) {
return nil, err
}

if m.Version != MetaVersion1 {
switch m.Version {
case MetaVersion1:
case MetaVersion2:
default:
return nil, errors.Errorf("unexpected meta file version %d", m.Version)
}

Expand Down