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

Use structured logging #50

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

uablrek
Copy link
Contributor

@uablrek uablrek commented Jul 3, 2024

Use structured logging in json format if -logging-format=json is specified. The same setup functions as for K8s core packages are used (component-base).

Also, contextual logging is used (beta in 1.30, so no feature-gateway is needed).

Fixes #48

This PR will be a draft until all code is changed to use structured/contextual logging.

@k8s-ci-robot k8s-ci-robot added the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Jul 3, 2024
@k8s-ci-robot k8s-ci-robot added cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. size/M Denotes a PR that changes 30-99 lines, ignoring generated files. labels Jul 3, 2024
@uablrek
Copy link
Contributor Author

uablrek commented Jul 3, 2024

/cc @pohly

@pohly Can you please review the updates in main() in the first commit? I don't want to do any fundamental mistakes. The rest I think I can manage.

@k8s-ci-robot k8s-ci-robot requested a review from pohly July 3, 2024 10:51
@uablrek
Copy link
Contributor Author

uablrek commented Jul 3, 2024

Example output:

# kubectl logs -n kube-system   kube-network-policies-8hb7p | jq
...
{
  "ts": 1720002972865.8306,
  "caller": "cache/reflector.go:359",
  "msg": "Caches populated for *v1.Pod from pkg/mod/k8s.io/[email protected]/tools/cache/reflector.go:232",
  "v": 2
}
{
  "ts": 1720002972953.2607,
  "caller": "cache/shared_informer.go:320",
  "msg": "Caches are synced for kube-network-policies",
  "v": 0
}
{
  "ts": 1720002972953.3674,
  "caller": "networkpolicy/metrics.go:61",
  "msg": "Registering metrics",
  "v": 0
}
{
  "ts": 1720002972953.4724,
  "caller": "networkpolicy/controller.go:344",
  "msg": "Syncing nftables rules",
  "v": 0
}

@uablrek
Copy link
Contributor Author

uablrek commented Jul 3, 2024

Lint complaints:

Error: cmd/main.go:81:3: exitAfterDefer: os.Exit will exit, and `defer cancel()` will not run (gocritic)

This is just as bad with klog.Fatalf, but lint misses that. A pattern seem to be:

func main() {
  os.Exit(run())
}
func run() int {
  return errorCode
}

Shall we use it? Else I restore klog.Fatalf in main()

I will call cancel() explicitly. (but since it's right before exit, it will not really matter)

@aojea
Copy link
Contributor

aojea commented Jul 3, 2024

func main() {
  os.Exit(run())
}
func run() int {
  return errorCode
}

that sounds like the right way to do it

@aojea
Copy link
Contributor

aojea commented Jul 9, 2024

@uablrek what is missing here? it lgtms

/lgtm
/approve

@k8s-ci-robot k8s-ci-robot added the lgtm "Looks good to me", indicates that a PR is ready to be merged. label Jul 9, 2024
@k8s-ci-robot
Copy link
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: aojea, uablrek

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@k8s-ci-robot k8s-ci-robot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Jul 9, 2024
@uablrek
Copy link
Contributor Author

uablrek commented Jul 10, 2024

@uablrek what is missing here? it lgtms

Lots and lots of Infof(), and friends, should be changed to InfoS().

Also i was planning to introduce contextual logging, but I think that can wait.

@k8s-ci-robot k8s-ci-robot removed the lgtm "Looks good to me", indicates that a PR is ready to be merged. label Jul 11, 2024
@k8s-ci-robot
Copy link
Contributor

New changes are detected. LGTM label has been removed.

@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 Jul 11, 2024
@uablrek
Copy link
Contributor Author

uablrek commented Jul 11, 2024

Structured logging allows a nice optimization possibility. Without this p.String() is always called, regardless of verbosity.

	// evaluatePacket() should be fast unless trace logging is enabled.
	// Logging optimization: We check if V(2) is enabled before hand,
	// rather than evaluating the all parameters make an unnecessary logger call
	tlogger := logger.V(2)
	if tlogger.Enabled() {
		tlogger.Info("Evaluating packet", "packet", p)
		tlogger = tlogger.WithValues("id", p.id)
	}

@@ -371,7 +373,7 @@ func (c *Controller) Run(ctx context.Context) error {

nf, err := nfqueue.Open(&config)
if err != nil {
klog.Infof("could not open nfqueue socket: %v", err)
logger.Info("could not open nfqueue socket", "error", err)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Logging like this exist at several places. I am unsure how to handle them. A general recommendation is to not log errors if you return them (let the caller decide). And normally logger.Error(err, ...) is used for logging errors, but then it will be at a higher log-level. I made a compromise by keeping the log at Info level.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

A way to keep info about what caused the error is to wrap them:

return fmt.Errorf("could not open nfqueue socket %w", err)

(ref: recent discussion on slack)

@uablrek
Copy link
Contributor Author

uablrek commented Jul 12, 2024

Example packet log in JSON format:

{
  "ts": 1720777151838.3552,
  "caller": "networkpolicy/controller.go:461",
  "msg": "Evaluating packet",
  "v": 2,
  "packet": {
    "Id": 9,
    "Family": "IPv4",
    "SrcIP": "11.0.3.3",
    "DstIP": "11.0.2.2",
    "Proto": "TCP",
    "SrcPort": 33803,
    "DstPort": 6000
  }
}

Text output is not altered:

I0712 09:53:52.257809       1 controller.go:461] "Evaluating packet" packet=<
        [8] 11.0.1.3:40243 11.0.2.2:6000 TCP
        00000000  00 00 a0 02 fa f0 19 33  00 00 02 04 05 b4 04 02  |.......3........|
        00000010  08 0a c1 d9 c1 bd 00 00  00 00 01 03 03 07        |..............|
 >

@uablrek uablrek marked this pull request as ready for review July 12, 2024 16:19
@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 Jul 12, 2024
@uablrek
Copy link
Contributor Author

uablrek commented Jul 12, 2024

I will squash commits later

@aojea
Copy link
Contributor

aojea commented Jul 12, 2024

let me know once is ready for merging

@k8s-ci-robot k8s-ci-robot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Jul 17, 2024
cmd/main.go Outdated
ctx, cancel := signal.NotifyContext(
context.Background(), os.Interrupt, unix.SIGINT)
defer cancel()
logger := klog.NewKlogr()
Copy link

Choose a reason for hiding this comment

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

This shouldn't be needed and might never give you a JSON logger.

Leave the context as it is. A klog.FromContext will then get the global default prepared by logsapi.ValidateAndApply.

Suggested change
logger := klog.NewKlogr()
logger := klog.FromContext(ctx)

cmd/main.go Outdated
context.Background(), os.Interrupt, unix.SIGINT)
defer cancel()
logger := klog.NewKlogr()
ctx = klog.NewContext(ctx, logger)
Copy link

Choose a reason for hiding this comment

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

Delete this.

@k8s-ci-robot k8s-ci-robot removed the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Jul 21, 2024
@uablrek uablrek force-pushed the structured-logging branch 2 times, most recently from 468ae28 to 0d6caa3 Compare July 21, 2024 09:39
@uablrek
Copy link
Contributor Author

uablrek commented Jul 21, 2024

Rebased, updated after review, and use klog.KObj. Ready for review.

Please note that payload is empty for TCP/SYN, which is the only TCP packets we see:

I0721 08:56:53.060501       1 controller.go:491] "Evaluating packet" packet=<
        [10] 11.0.4.3:34751 11.0.4.2:6000 TCP
 >

@uablrek
Copy link
Contributor Author

uablrek commented Jul 21, 2024

let me know once is ready for merging

@aojea Ready for review at least. I hope for merging. No logic is altered (except in main()), but very many log printouts

@k8s-ci-robot k8s-ci-robot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Sep 4, 2024
Klog is initiated with support for json output, and a context
with a logger is created. The context catches term signals.
Log packets in JSON format for -logging-format=json.
@k8s-ci-robot k8s-ci-robot removed the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Sep 4, 2024
@k8s-ci-robot k8s-ci-robot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Oct 8, 2024
@k8s-ci-robot
Copy link
Contributor

PR needs rebase.

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-sigs/prow 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. needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. 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.

Use structured logging
4 participants