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

Add Backtrace APIs to klog #323

Closed
wants to merge 1 commit into from
Closed

Conversation

pchan
Copy link

@pchan pchan commented May 7, 2022

What this PR does / why we need it:
This PR adds Backtrace APIs. See #316 for justification.

Which issue(s) this PR fixes (optional, in fixes #<issue number>(, fixes #<issue_number>, ...) format, will close the issue(s) when PR gets merged):
Fixes #316

Special notes for your reviewer:
This is an experimental code meant as PoC. The code will be formalized once the APIs themselves are approved/frozen.

Please confirm that if this PR changes any image versions, then that's the sole change this PR makes.
This PR changes API.

@k8s-ci-robot k8s-ci-robot added do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. labels May 7, 2022
@k8s-ci-robot
Copy link

Welcome @pchan!

It looks like this is your first PR to kubernetes/klog 🎉. Please refer to our pull request process documentation to help your PR have a smooth ride to approval.

You will be prompted by a bot to use commands during the review process. Do not be afraid to follow the prompts! It is okay to experiment. Here is the bot commands documentation.

You can also check if kubernetes/klog has its own contribution guidelines.

You may want to refer to our testing guide if you run into trouble with your tests not passing.

If you are having difficulty getting your pull request seen, please follow the recommended escalation practices. Also, for tips and tricks in the contribution process you may want to read the Kubernetes contributor cheat sheet. We want to make sure your contribution gets all the attention it needs!

Thank you, and welcome to Kubernetes. 😃

@k8s-ci-robot k8s-ci-robot added the size/M Denotes a PR that changes 30-99 lines, ignoring generated files. label May 7, 2022
klog.go Outdated Show resolved Hide resolved
klog.go Outdated
pc := make([]uintptr, 100)
n := runtime.Callers(mytrace.skip+1, pc)

if n == 0 {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need unit tests for this.

klog.go Outdated Show resolved Hide resolved
@k8s-ci-robot k8s-ci-robot added size/L Denotes a PR that changes 100-499 lines, ignoring generated files. and removed size/M Denotes a PR that changes 30-99 lines, ignoring generated files. labels May 11, 2022
Copy link

@pohly pohly left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you put the new code into a separate backtrace.go file? klog.go is large enough as it is....

You can also squash all changes into a single commit. I'll use the diff between force-pushes to track changes.

klog.go Outdated Show resolved Hide resolved
klog.go Outdated Show resolved Hide resolved
klog.go Outdated Show resolved Hide resolved
klog.go Outdated Show resolved Hide resolved
klog.go Outdated Show resolved Hide resolved
klog.go Outdated Show resolved Hide resolved
klog.go Outdated Show resolved Hide resolved
@pchan
Copy link
Author

pchan commented May 21, 2022

Added unit tests for the backtrace APIs.

Copy link

@pohly pohly left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See also my earlier comment about moving this code out of klog.go.

klog.go Outdated Show resolved Hide resolved
klog_test.go Outdated Show resolved Hide resolved
klog_test.go Outdated Show resolved Hide resolved
klog_test.go Outdated Show resolved Hide resolved
klog_test.go Outdated Show resolved Hide resolved
klog_test.go Outdated Show resolved Hide resolved
klog_test.go Outdated Show resolved Hide resolved
klog_test.go Outdated Show resolved Hide resolved
@pchan
Copy link
Author

pchan commented May 25, 2022

See also my earlier comment about moving this code out of klog.go.

I will move the updated code to backtrace.go/backtrace_test.go in the next checkin.

@pchan pchan changed the title [WIP] Add Backtrace APIs to klog Add Backtrace APIs to klog May 25, 2022
@k8s-ci-robot k8s-ci-robot removed the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label May 25, 2022
@pchan
Copy link
Author

pchan commented May 25, 2022

See also my earlier comment about moving this code out of klog.go.

I will move the updated code to backtrace.go/backtrace_test.go in the next checkin.

Latest checkin moves the Backtrace API to its own file.

klog.go Outdated Show resolved Hide resolved
Copy link

@pohly pohly left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for all your work on this. However, I still find it hard to see that TestBackTrace really tests for the right behavior. It also doesn't cover several edge cases. May I suggest to use a different approach?

Instead of doing partial tests for some expected lines in the backtrace, let's compare the entire backtrace after removing a few parts that we allow to vary.

Here's an implementation of that:

/*
Copyright 2022 The Kubernetes Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package klog_test

import (
	"fmt"
	"regexp"
	"runtime"
	"strings"
	"testing"

	"k8s.io/klog/v2"
)

// The tests are sensitive to line changes in the following code. Here are some
// lines that can be added or removed to compensate for import statement
// changes.
//
//
//
//
//
//
//
//
// This must be line 40 (first line is 1).

func outer(callback func() interface{}) interface{} {
	return inner(callback)
}

func inner(callback func() interface{}) interface{} {
	return callback()
}

//
//
//
//
//
//
//
//
//
//
// This must be line 60. Any line number higher than that gets ignored by normalizeBacktrace.

func TestBacktrace(t *testing.T) {
	for name, tt := range map[string]struct {
		callback func() interface{}
		expected string
	}{
		"simple": {
			callback: func() interface{} { return klog.Backtrace() },
			expected: `k8s.io/klog/v2_test.TestBacktrace.funcX():
	/nvme/gopath/src/k8s.io/klog/backtrace_test.go:xxx
k8s.io/klog/v2_test.inner():
	/nvme/gopath/src/k8s.io/klog/backtrace_test.go:47
k8s.io/klog/v2_test.outer():
	/nvme/gopath/src/k8s.io/klog/backtrace_test.go:43
k8s.io/klog/v2_test.TestBacktrace.funcX():
	/nvme/gopath/src/k8s.io/klog/backtrace_test.go:xxx
`,
		},

		"skip0": {
			callback: func() interface{} { return klog.Backtrace(klog.BacktraceSkip(0)) },
			expected: `k8s.io/klog/v2_test.TestBacktrace.funcX():
	/nvme/gopath/src/k8s.io/klog/backtrace_test.go:xxx
k8s.io/klog/v2_test.inner():
	/nvme/gopath/src/k8s.io/klog/backtrace_test.go:47
k8s.io/klog/v2_test.outer():
	/nvme/gopath/src/k8s.io/klog/backtrace_test.go:43
k8s.io/klog/v2_test.TestBacktrace.funcX():
	/nvme/gopath/src/k8s.io/klog/backtrace_test.go:xxx
`,
		},

		"skip1": {
			callback: func() interface{} { return klog.Backtrace(klog.BacktraceSkip(1)) },
			expected: `k8s.io/klog/v2_test.inner():
	/nvme/gopath/src/k8s.io/klog/backtrace_test.go:47
k8s.io/klog/v2_test.outer():
	/nvme/gopath/src/k8s.io/klog/backtrace_test.go:43
k8s.io/klog/v2_test.TestBacktrace.funcX():
	/nvme/gopath/src/k8s.io/klog/backtrace_test.go:xxx
`,
		},

		"skip2": {
			callback: func() interface{} { return klog.Backtrace(klog.BacktraceSkip(2)) },
			expected: `k8s.io/klog/v2_test.outer():
	/nvme/gopath/src/k8s.io/klog/backtrace_test.go:43
k8s.io/klog/v2_test.TestBacktrace.funcX():
	/nvme/gopath/src/k8s.io/klog/backtrace_test.go:xxx
`,
		},

		"trace1": {
			callback: func() interface{} { return klog.Backtrace(klog.BacktraceSize(1)) },
			expected: `k8s.io/klog/v2_test.TestBacktrace.funcX():
	/nvme/gopath/src/k8s.io/klog/backtrace_test.go:xxx
`,
		},

		"trace2": {
			callback: func() interface{} { return klog.Backtrace(klog.BacktraceSize(2)) },
			expected: `k8s.io/klog/v2_test.TestBacktrace.funcX():
	/nvme/gopath/src/k8s.io/klog/backtrace_test.go:xxx
k8s.io/klog/v2_test.inner():
	/nvme/gopath/src/k8s.io/klog/backtrace_test.go:47
`,
		},

		"skip1-trace1": {
			callback: func() interface{} { return klog.Backtrace(klog.BacktraceSize(1), klog.BacktraceSkip(1)) },
			expected: `k8s.io/klog/v2_test.inner():
	/nvme/gopath/src/k8s.io/klog/backtrace_test.go:47
`,
		},
	} {
		t.Run(name, func(t *testing.T) {
			backtrace := outer(tt.callback)
			actual := normalizeBacktrace(t, backtrace)
			if actual != tt.expected {
				t.Errorf("Wrong backtrace. Expected:\n%s\nActual:\n%s\n", tt.expected, actual)
			}
		})
	}
}

func normalizeBacktrace(t *testing.T, backtrace interface{}) string {
	str := backtrace.(fmt.Stringer).String()

	// This matches the stack entry for the testing package:
	// testing.tRunner():
	//     /nvme/gopath/go-1.18.1/src/testing/testing.go:1439
	//
	// It and all following entries vary and get removed.
	end := regexp.MustCompile(`(?m)^testing\.`).FindStringIndex(str)
	if end != nil {
		str = str[:end[0]]
	}

	// Remove varying line numbers.
	str = regexp.MustCompile(`(?m):([67890][0-9]|[1-9][0-9][0-9])$`).ReplaceAllString(str, ":xxx")

	// Remove varying anonymous function numbers.
	str = regexp.MustCompile(`\.func[[:digit:]]+`).ReplaceAllString(str, ".funcX")

	return str
}

func TestBacktraceAll(t *testing.T) {
	_, callerFile, _, _ := runtime.Caller(0)
	actual := klog.Backtrace(klog.BacktraceAll(true)).(fmt.Stringer).String()
	t.Logf("Backtrace:\n%s\n", actual)

	if strings.Contains(actual, callerFile) == false {
		t.Errorf("Expected to see %q in trace:\n%s", callerFile, actual)
	}

	// Pattern: goroutine 7 [running]:
	p := regexp.MustCompile("(?m)(^goroutine [0-9]*.\\[.*\\]*:)")
	if len(p.FindAllString(actual, -1)) < 2 {
		t.Errorf("Expected more than 1 goroutine stack to be printed, got:\n%s", actual)
	}
}

If you agree, can you replace your copy of that file and squash everything into one commit?

@pchan
Copy link
Author

pchan commented May 25, 2022

Thanks for all your work on this. However, I still find it hard to see that TestBackTrace really tests for the right behavior. It also doesn't cover several edge cases. May I suggest to use a different approach?

Instead of doing partial tests for some expected lines in the backtrace, let's compare the entire backtrace after removing a few parts that we allow to vary.

One problem is we need normalize the full paths too.

  "simple": {
  	callback: func() interface{} { return klog.Backtrace() },
  	expected: `k8s.io/klog/v2_test.TestBacktrace.funcX():
              /nvme/gopath/src/k8s.io/klog/backtrace_test.go:xxx
               k8s.io/klog/v2_test.inner():
             /nvme/gopath/src/k8s.io/klog/backtrace_test.go:47
                   k8s.io/klog/v2_test.outer():
            /nvme/gopath/src/k8s.io/klog/backtrace_test.go:43
             k8s.io/klog/v2_test.TestBacktrace.funcX():
           /nvme/gopath/src/k8s.io/klog/backtrace_test.go:xxx

In the above case we will have a mismatch based on the path /nvme/gopath/src/k8s.io/klog/backtrace_test.go:xxx, which will vary. We will need to extend normalize_backtrace to account for these too.

@pohly
Copy link

pohly commented May 25, 2022

In the above case we will have a mismatch based on the path /nvme/gopath/src/k8s.io/klog/backtrace_test.go:xxx, which will vary. We will need to extend normalize_backtrace to account for these too.

You are right. Can you add that?

@pchan
Copy link
Author

pchan commented May 25, 2022

In the above case we will have a mismatch based on the path /nvme/gopath/src/k8s.io/klog/backtrace_test.go:xxx, which will vary. We will need to extend normalize_backtrace to account for these too.

You are right. Can you add that?

I have attempted a simple normalization. Please review.

backtrace_test.go Outdated Show resolved Hide resolved
@pchan
Copy link
Author

pchan commented May 29, 2022

Is there anthing pending ? We are planning on getting this done for 1.25 K8s enhancememt so checking to see if we are good to merge.

@pohly
Copy link

pohly commented May 30, 2022

/ok-to-test

@k8s-ci-robot k8s-ci-robot added the ok-to-test Indicates a non-member PR verified by an org member that is safe to test. label May 30, 2022
Copy link

@pohly pohly left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please squash into a single commit with a suitable commit message.

@pohly
Copy link

pohly commented May 30, 2022

@serathius: this is based on my own API proposal, therefore someone else should review it. Can you take a look?

@dims
Copy link
Member

dims commented May 31, 2022

/approve

@pohly
Copy link

pohly commented May 31, 2022

This confused me because it looked like a reference to the non longer existing BacktraceAll stand-alone function. As it stands now, it compares a function ("Backtrace") with an option ("BacktraceAll"). Depending on the option, "Backtrace" uses different mechanisms.

A better commit message would be to describe why this is a useful change.

@pchan
Copy link
Author

pchan commented May 31, 2022

A better commit message would be to describe why this is a useful change.

How about this:

The backtrace APIs allows a developer or klog component to embed backtraces in the log entry aiding debugging.

@pohly
Copy link

pohly commented May 31, 2022

Scratch the "or klog component" and it looks good to me.

@pohly
Copy link

pohly commented Jun 1, 2022

/assign @serathius

The backtrace APIs allows a developer to embed backtraces in the log entry aiding debugging.
@pchan
Copy link
Author

pchan commented Jun 1, 2022

Scratch the "or klog component" and it looks good to me.

Updated the commit message.

Copy link
Member

@thockin thockin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why does this belong in klog? It seems convenient, at best. Like why not a kdbg package or something? Like logr itself, this seems simple and generally useful.

Should it go in github/com/go-logr/dbg? or k8s.io/kdbg? Or is this just "good enough, leave it alone, Tim" ?

@thockin thockin self-assigned this Jun 6, 2022
@pohly
Copy link

pohly commented Jun 6, 2022

Why does this belong in klog? It seems convenient, at best.

For the same reason that KObj and KObjSlice were added to klog: to have a single package that provides everything that is needed for Kubernetes logging. So yes, mostly convenience.

But you are right, in contrast to KObjand friends the new helper is useful also outside of Kubernetes code and it shouldn't be needed often in Kubernetes, so a separate import is not a big burden. Do we need a separate repo, though? How about github.com/go-logr/logr/dbg? Just thinking aloud here.

github/com/go-logr/dbg also works. It's easier to set up than a k8s.io repo (regardless whether it is staging or separate). k8s.io/kdbg also feels wrong because the code is complete independent of Kubernetes.

@thockin
Copy link
Member

thockin commented Jun 6, 2022 via email

pohly pushed a commit to go-logr/lib that referenced this pull request Jun 7, 2022
The backtrace APIs allows a developer to embed backtraces in a log entry
aiding debugging.

Signed-off-by: Patrick Ohly <patrick.ohly@intel.com>

Copied from kubernetes/klog#323
pohly pushed a commit to go-logr/lib that referenced this pull request Jun 7, 2022
The backtrace APIs allows a developer to embed backtraces in a log entry
aiding debugging.

Signed-off-by: Patrick Ohly <patrick.ohly@intel.com>

Copied from kubernetes/klog#323
pohly pushed a commit to go-logr/lib that referenced this pull request Jun 7, 2022
The backtrace APIs allows a developer to embed backtraces in a log entry
aiding debugging.

Signed-off-by: Patrick Ohly <patrick.ohly@intel.com>

Copied from kubernetes/klog#323
@pohly
Copy link

pohly commented Jun 7, 2022

I'm a little wary of go-logr/logr/dbg - what principle decides where that stops?

Same for go-logr/dbg - do we expect any other code to land there? An entire package that just holds a single feature seems overkill to me. go-logr/loghelper might be better because loghelper.<something> works for <something> besides Backtrace.

Let's try that on for size... I created a private https://github.com/go-logr/loghelper and populated it with the code from this PR. I had to make some minor changes to pass the linter settings.

@pchan: I don't see how I can grant you access to it, but here's the diff compared to your code:

pohly@pohly-desktop:/nvme/gopath/src/github.com/go-logr/loghelper$ diff ../../../k8s.io/klog/backtrace.go backtrace.go 
2c2
< Copyright 2022 The Kubernetes Authors.
---
> Copyright 2022 The logr Authors.
16c16,17
< package klog
---
> 
> package loghelper
119c120
< 		s = s + fmt.Sprintf("%s():\n\t%s:%v\n", frame.Function, frame.File, frame.Line)
---
> 		s += fmt.Sprintf("%s():\n\t%s:%v\n", frame.Function, frame.File, frame.Line)
127a129,147
> 	return trace
> }
> 
> // stacks is a wrapper for runtime.Stack that attempts to recover the data for all goroutines.
> func stacks(all bool) []byte {
> 	// We don't know how big the traces are, so grow a few times if they don't fit. Start large, though.
> 	n := 10000
> 	if all {
> 		n = 100000
> 	}
> 	var trace []byte
> 	for i := 0; i < 5; i++ {
> 		trace = make([]byte, n)
> 		nbytes := runtime.Stack(trace, all)
> 		if nbytes < len(trace) {
> 			return trace[:nbytes]
> 		}
> 		n *= 2
> 	}
pohly@pohly-desktop:/nvme/gopath/src/github.com/go-logr/loghelper$ diff ../../../k8s.io/klog/backtrace_test.go backtrace_test.go 
2c2
< Copyright 2022 The Kubernetes Authors.
---
> Copyright 2022 The logr Authors.
17c17
< package klog_test
---
> package loghelper_test
26c26
< 	"k8s.io/klog/v2"
---
> 	"github.com/go-logr/loghelper"
68,69c68,69
< 			callback: func() interface{} { return klog.Backtrace() },
< 			expected: `k8s.io/klog/v2_test.TestBacktrace.funcX():
---
> 			callback: func() interface{} { return loghelper.Backtrace() },
> 			expected: `github.com/go-logr/loghelper_test.TestBacktrace.funcX():
71c71
< k8s.io/klog/v2_test.inner():
---
> github.com/go-logr/loghelper_test.inner():
73c73
< k8s.io/klog/v2_test.outer():
---
> github.com/go-logr/loghelper_test.outer():
75c75
< k8s.io/klog/v2_test.TestBacktrace.funcX():
---
> github.com/go-logr/loghelper_test.TestBacktrace.funcX():
81,82c81,82
< 			callback: func() interface{} { return klog.Backtrace(klog.BacktraceSkip(0)) },
< 			expected: `k8s.io/klog/v2_test.TestBacktrace.funcX():
---
> 			callback: func() interface{} { return loghelper.Backtrace(loghelper.BacktraceSkip(0)) },
> 			expected: `github.com/go-logr/loghelper_test.TestBacktrace.funcX():
84c84
< k8s.io/klog/v2_test.inner():
---
> github.com/go-logr/loghelper_test.inner():
86c86
< k8s.io/klog/v2_test.outer():
---
> github.com/go-logr/loghelper_test.outer():
88c88
< k8s.io/klog/v2_test.TestBacktrace.funcX():
---
> github.com/go-logr/loghelper_test.TestBacktrace.funcX():
94,95c94,95
< 			callback: func() interface{} { return klog.Backtrace(klog.BacktraceSkip(1)) },
< 			expected: `k8s.io/klog/v2_test.inner():
---
> 			callback: func() interface{} { return loghelper.Backtrace(loghelper.BacktraceSkip(1)) },
> 			expected: `github.com/go-logr/loghelper_test.inner():
97c97
< k8s.io/klog/v2_test.outer():
---
> github.com/go-logr/loghelper_test.outer():
99c99
< k8s.io/klog/v2_test.TestBacktrace.funcX():
---
> github.com/go-logr/loghelper_test.TestBacktrace.funcX():
105,106c105,106
< 			callback: func() interface{} { return klog.Backtrace(klog.BacktraceSkip(2)) },
< 			expected: `k8s.io/klog/v2_test.outer():
---
> 			callback: func() interface{} { return loghelper.Backtrace(loghelper.BacktraceSkip(2)) },
> 			expected: `github.com/go-logr/loghelper_test.outer():
108c108
< k8s.io/klog/v2_test.TestBacktrace.funcX():
---
> github.com/go-logr/loghelper_test.TestBacktrace.funcX():
114,115c114,115
< 			callback: func() interface{} { return klog.Backtrace(klog.BacktraceSize(1)) },
< 			expected: `k8s.io/klog/v2_test.TestBacktrace.funcX():
---
> 			callback: func() interface{} { return loghelper.Backtrace(loghelper.BacktraceSize(1)) },
> 			expected: `github.com/go-logr/loghelper_test.TestBacktrace.funcX():
121,122c121,122
< 			callback: func() interface{} { return klog.Backtrace(klog.BacktraceSize(2)) },
< 			expected: `k8s.io/klog/v2_test.TestBacktrace.funcX():
---
> 			callback: func() interface{} { return loghelper.Backtrace(loghelper.BacktraceSize(2)) },
> 			expected: `github.com/go-logr/loghelper_test.TestBacktrace.funcX():
124c124
< k8s.io/klog/v2_test.inner():
---
> github.com/go-logr/loghelper_test.inner():
130,131c130,131
< 			callback: func() interface{} { return klog.Backtrace(klog.BacktraceSize(1), klog.BacktraceSkip(1)) },
< 			expected: `k8s.io/klog/v2_test.inner():
---
> 			callback: func() interface{} { return loghelper.Backtrace(loghelper.BacktraceSize(1), loghelper.BacktraceSkip(1)) },
> 			expected: `github.com/go-logr/loghelper_test.inner():
147c147,151
< 	str := backtrace.(fmt.Stringer).String()
---
> 	stringer, ok := backtrace.(fmt.Stringer)
> 	if !ok {
> 		t.Fatal("expected fmt.Stringer")
> 	}
> 	str := stringer.String()
173c177,181
< 	actual := klog.Backtrace(klog.BacktraceAll(true)).(fmt.Stringer).String()
---
> 	stringer, ok := loghelper.Backtrace(loghelper.BacktraceAll(true)).(fmt.Stringer)
> 	if !ok {
> 		t.Fatal("expected fmt.Stringer")
> 	}
> 	actual := stringer.String()
181c189
< 	p := regexp.MustCompile("(?m)(^goroutine [0-9]*.\\[.*\\]*:)")
---
> 	p := regexp.MustCompile(`(?m)(^goroutine [0-9]*.\[.*\]*:)`)

Are you okay with that?

@thockin: shall we go with that? I can also rename the repo to dbg, if that is what you prefer.

@pchan
Copy link
Author

pchan commented Jun 9, 2022

@pchan: I don't see how I can grant you access to it, but here's the diff compared to your code:

Are you okay with that?

I am ok with the change.

@thockin
Copy link
Member

thockin commented Jun 10, 2022

Shouldn't it be helpr :)

@thockin
Copy link
Member

thockin commented Jun 10, 2022

Talking API:

  1. Should it be a sub-pkg?
import "github.com/go-logr/helpr"
//...
loghelpr.Backtrace(helpr.BacktraceSize(42))

vs

import "github.com/go-logr/helpr/backtrace"
//...
loghelpr.Backtrace(backtrace.Size(42))

??

  1. Should BacktraceAll be an option on Backtrace() or should there be 2 top-level functions, which return different types with different sets of Options? E.g. helpr.Backtrace(helpr.BacktraceSkip(6)) vs helpr.BacktraceAll(helpr.BacktraceAllSkip(6)) ? Or maybe:
type BacktraceOption interface{
    optionBacktrace(traceT)
}

type BacktraceAllOption interface{
    optionBacktraceAll(traceallT)
}

type BacktraceOneOrAllOption interface {
        optionBacktrace(traceT)
        optionBacktraceAll(traceallT)
}

?? Maybe not.

  1. Rename BacktraceSize to BacktraceFrames?

@pohly
Copy link

pohly commented Jun 10, 2022

All the other go-logr/*r repos (stdr, gologr, zapr) are logger implementations. go-logr/benchmark and the new one aren't. I still prefer go-logr/loghelper.

  1. Should it be a sub-pkg?

go-logr/loghelper/dbg makes sense to me. dbg.Backtrace is okay and text completion in an editor with be able to find the option functions.

  1. Should BacktraceAll be an option on Backtrace() or should there be 2 top-level functions

I went through that with @pchan earlier. I prefer a single Backtrace because it keeps the API smaller. It also may be simpler to switch between more or less details just by changing options, compared to having to switch between different functions.

  1. Rename BacktraceSize to BacktraceFrames?

Works for me.

@thockin
Copy link
Member

thockin commented Jun 10, 2022

OK with the above, I think - push that as a PR on th eloghelper repo and make it public?

Should we tag it 1.0.0 or just let it ride for a bit?

@pohly
Copy link

pohly commented Jun 10, 2022

OK with the above, I think - push that as a PR on the loghelper repo and make it public?

Will do.

Should we tag it 1.0.0 or just let it ride for a bit?

It's a brand-new API. Let's give it some more time before we commit to a stable v1 API.

@pohly
Copy link

pohly commented Jun 10, 2022

One more thought: if all code is going to be in sub-packages, then we don't need a (relatively) unique name for the repo. With that in mind, I prefer go-logr/helper/dbg - no redundancy in the path and dbg.Backtrace in code is fine.

@thockin
Copy link
Member

thockin commented Jun 10, 2022

Why not go-logr/lib/dbg We're on the edge of creating another "util" repo which always ends badly. Just saying. Let's lay out some rules for what can go in here, especially WRT deps.

@pohly
Copy link

pohly commented Jun 11, 2022

Why not go-logr/lib/dbg

That also works.

We're on the edge of creating another "util" repo which always ends badly. Just saying.

I had the same thought. But what's the alternative for such code?

Let's lay out some rules for what can go in here, especially WRT deps.

As with logr, I'll draw the line at a very strict "only Go standard library"

... and go-logr/logr itself.

pohly pushed a commit to go-logr/lib that referenced this pull request Jun 13, 2022
The backtrace APIs allows a developer to embed backtraces in a log entry
aiding debugging.

Signed-off-by: Patrick Ohly <patrick.ohly@intel.com>

Copied from kubernetes/klog#323
pohly pushed a commit to go-logr/lib that referenced this pull request Jun 13, 2022
The backtrace APIs allows a developer to embed backtraces in a log entry
aiding debugging.

Signed-off-by: Patrick Ohly <patrick.ohly@intel.com>

Copied from kubernetes/klog#323
@pohly
Copy link

pohly commented Jun 13, 2022

See https://github.com/go-logr/lib and #328 for a PR that references the new function in a doc comment.

/close

@k8s-ci-robot
Copy link

@pohly: Closed this PR.

In response to this:

See https://github.com/go-logr/lib and #328 for a PR that references the new function in a doc comment.

/close

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
approved Indicates a PR has been approved by an approver from all required OWNERS files. cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. ok-to-test Indicates a non-member PR verified by an org member that is safe to test. size/L Denotes a PR that changes 100-499 lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

dumping stacks during klog.Fatal
6 participants