Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Set time and duration of profile #18

Merged
merged 6 commits into from Aug 27, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
12 changes: 11 additions & 1 deletion fgprof.go
Expand Up @@ -14,6 +14,8 @@ import (
// that needs to be invoked by the caller to stop the profiling and write the
// results to w using the given format.
func Start(w io.Writer, format Format) func() error {
startTime := time.Now()

// Go's CPU profiler uses 100hz, but 99hz might be less likely to result in
// accidental synchronization with the program we're profiling.
const hz = 99
Expand All @@ -39,7 +41,15 @@ func Start(w io.Writer, format Format) func() error {

return func() error {
stopCh <- struct{}{}
return writeFormat(w, stackCounts.HumanMap(prof.SelfFrame()), format, hz)
endTime := time.Now()
return writeFormat(
w,
stackCounts.HumanMap(prof.SelfFrame()),
format,
hz,
startTime,
endTime,
)
}
}

Expand Down
9 changes: 6 additions & 3 deletions format.go
Expand Up @@ -5,6 +5,7 @@ import (
"io"
"sort"
"strings"
"time"

"github.com/google/pprof/profile"
)
Expand All @@ -21,12 +22,12 @@ const (
FormatPprof Format = "pprof"
)

func writeFormat(w io.Writer, s map[string]int, f Format, hz int) error {
func writeFormat(w io.Writer, s map[string]int, f Format, hz int, startTime, endTime time.Time) error {
switch f {
case FormatFolded:
return writeFolded(w, s)
case FormatPprof:
return toPprof(s, hz).Write(w)
return toPprof(s, hz, startTime, endTime).Write(w)
default:
return fmt.Errorf("unknown format: %q", f)
}
Expand All @@ -42,14 +43,16 @@ func writeFolded(w io.Writer, s map[string]int) error {
return nil
}

func toPprof(s map[string]int, hz int) *profile.Profile {
func toPprof(s map[string]int, hz int, startTime, endTime time.Time) *profile.Profile {
functionID := uint64(1)
locationID := uint64(1)
line := int64(1)

p := &profile.Profile{}
m := &profile.Mapping{ID: 1, HasFunctions: true}
p.Period = int64(1e9 / hz) // Number of nanoseconds between samples.
p.TimeNanos = startTime.UnixNano()
p.DurationNanos = int64(endTime.Sub(startTime))
p.Mapping = []*profile.Mapping{m}
p.SampleType = []*profile.ValueType{
{
Expand Down
11 changes: 10 additions & 1 deletion format_test.go
Expand Up @@ -3,6 +3,7 @@ package fgprof
import (
"strings"
"testing"
"time"
)

func Test_toPprof(t *testing.T) {
Expand All @@ -11,14 +12,22 @@ func Test_toPprof(t *testing.T) {
"foo": 1,
}

p := toPprof(s, 99)
before := time.Local
defer func() { time.Local = before }()
time.Local = time.UTC

start := time.Date(2022, 8, 27, 14, 32, 23, 0, time.UTC)
end := start.Add(time.Second)
p := toPprof(s, 99, start, end)
if err := p.CheckValid(); err != nil {
t.Fatal(err)
}

want := strings.TrimSpace(`
PeriodType: wallclock nanoseconds
Period: 10101010
Time: 2022-08-27 14:32:23 +0000 UTC
Duration: 1s
Samples:
samples/count time/nanoseconds
1 10101010: 1
Expand Down