GithubHelp home page GithubHelp logo

kubernetes / klog Goto Github PK

View Code? Open in Web Editor NEW

This project forked from golang/glog

511.0 19.0 214.0 909 KB

Leveled execution logs for Go (fork of https://github.com/golang/glog)

License: Apache License 2.0

Go 99.12% Shell 0.88%
k8s-sig-architecture

klog's Introduction

klog

klog is a permanent fork of https://github.com/golang/glog.

Why was klog created?

The decision to create klog was one that wasn't made lightly, but it was necessary due to some drawbacks that are present in glog. Ultimately, the fork was created due to glog not being under active development; this can be seen in the glog README:

The code in this repo [...] is not itself under development

This makes us unable to solve many use cases without a fork. The factors that contributed to needing feature development are listed below:

  • glog presents a lot "gotchas" and introduces challenges in containerized environments, all of which aren't well documented.
  • glog doesn't provide an easy way to test logs, which detracts from the stability of software using it
  • A long term goal is to implement a logging interface that allows us to add context, change output format, etc.

Historical context is available here:

Release versioning

Semantic versioning is used in this repository. It contains several Go modules with different levels of stability:

  • k8s.io/klog/v2 - stable API, vX.Y.Z tags
  • examples - no stable API, no tags, no intention to ever stabilize

Exempt from the API stability guarantee are items (packages, functions, etc.) which are marked explicitly as EXPERIMENTAL in their docs comment. Those may still change in incompatible ways or get removed entirely. This can only be used for code that is used in tests to avoid situations where non-test code from two different Kubernetes dependencies depends on incompatible releases of klog because an experimental API was changed.


How to use klog

  • Replace imports for "github.com/golang/glog" with "k8s.io/klog/v2"
  • Use klog.InitFlags(nil) explicitly for initializing global flags as we no longer use init() method to register the flags
  • You can now use log_file instead of log_dir for logging to a single file (See examples/log_file/usage_log_file.go)
  • If you want to redirect everything logged using klog somewhere else (say syslog!), you can use klog.SetOutput() method and supply a io.Writer. (See examples/set_output/usage_set_output.go)
  • For more logging conventions (See Logging Conventions)
  • See our documentation on pkg.go.dev/k8s.io.

NOTE: please use the newer go versions that support semantic import versioning in modules, ideally go 1.11.4 or greater.

Coexisting with klog/v2

See this example to see how to coexist with both klog/v1 and klog/v2.

Coexisting with glog

This package can be used side by side with glog. This example shows how to initialize and synchronize flags from the global flag.CommandLine FlagSet. In addition, the example makes use of stderr as combined output by setting alsologtostderr (or logtostderr) to true.

Community, discussion, contribution, and support

Learn how to engage with the Kubernetes community on the community page.

You can reach the maintainers of this project at:

Code of conduct

Participation in the Kubernetes community is governed by the Kubernetes Code of Conduct.


glog

Leveled execution logs for Go.

This is an efficient pure Go implementation of leveled logs in the manner of the open source C++ package https://github.com/google/glog

By binding methods to booleans it is possible to use the log package without paying the expense of evaluating the arguments to the log. Through the -vmodule flag, the package also provides fine-grained control over logging at the file level.

The comment from glog.go introduces the ideas:

Package glog implements logging analogous to the Google-internal
C++ INFO/ERROR/V setup.  It provides functions Info, Warning,
Error, Fatal, plus formatting variants such as Infof. It
also provides V-style logging controlled by the -v and
-vmodule=file=2 flags.

Basic examples:

	glog.Info("Prepare to repel boarders")

	glog.Fatalf("Initialization failed: %s", err)

See the documentation of the V function for an explanation
of these examples:

	if glog.V(2) {
		glog.Info("Starting transaction...")
	}

	glog.V(2).Infoln("Processed", nItems, "elements")

The repository contains an open source version of the log package used inside Google. The master copy of the source lives inside Google, not here. The code in this repo is for export only and is not itself under development. Feature requests will be ignored.

Send bug reports to [email protected].

klog's People

Contributors

aimuz avatar astraw99 avatar bentheelder avatar blaubaer avatar christopherhein avatar dean-coakley avatar dims avatar dsymonds avatar fatsheep9146 avatar greut avatar harshanarayana avatar joelsmith avatar k8s-ci-robot avatar lsytj0413 avatar mowangdk avatar mtaufen avatar munnerz avatar pohly avatar rf232 avatar robpike avatar scaat avatar serathius avatar tahsinrahman avatar thockin avatar umangachapagain avatar vanou avatar vincepri avatar wyyxd2017 avatar yuwenma avatar yuzhiquan avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

klog's Issues

klogr: Don't print level=n in a log line

/kind bug

What steps did you take and what happened:
When printing logs I see a lot of level="0" or level="1" etc.

There is no reason to print this information and only adds to the difficulty of reading lines. If anything the level could be similar to the I or E that starts an Info or Error Log, but it does not need a whole field.

Anything else you would like to add:

The change is a matter of removing the lvlStr in this function:

https://github.com/kubernetes/klog/blob/master/klogr/klogr.go#L143-L148

edit: "no reason" is too strong. There may be a use case for leaving this in, but I can't think of it beyond some other system parsing logs and wanting to only see specific log lines. Or perhaps logging -vMAX and then filtering on your logging backend.

Avoid log truncation due to log-rotation delays (when logfiles exceeds 1.8GB faster than log rotation)

/kind feature
(mirrored from k/k issue 76210
Describe the solution you'd like
[A clear and concise description of what you want to happen.]
klog supports "log-file" flag to specify the log file path. However, when the logfile size reaches 1.8GiB and log-rotation hasn't happened, the older logs will be truncated. See details in PR76190.

We want to keep all the log messages. If the log file goes too large, we expect to the older logs to be stored in a separate file kube-apiserver.log,gz..

Anything else you would like to add:
[Miscellaneous information that will assist in solving the issue.]
This issue needs to be fixed at least 1 month before v1.15. Since it blocks some v1.15 release features (like rebasing images from debian/alpine to distroless heavily depends on the klog feature).

Support log metric

/kind feature

Describe the solution you'd like
Collect log statistics and expose metric API.
collect information like TAG, log type, log detail, count etc.

Anything else you would like to add:

-vmodule should allow level -1

/kind bug

It is possible to pass the option -v -1 to disable level 0 logging, in which case only Errors are logged. However, it is not possible to pass a negative number for logging in a particular module, i.e., with the -vmodule option.

What steps did you take and what happened:

: logtest 114; go build && ./logtest -vmodule klogr=-1
invalid value "klogr=-1" for flag -vmodule: negative value for vmodule level

What did you expect to happen:

No error message, all log messages other than Errors for the specified module silenced.

Anything else you would like to add:

klog.SetOutput() triggers data race

/kind bug

What steps did you take and what happened:
In CoreDNS we set klog.SetOutput(os.Stdout) to unify all our logging to standard ouput. In a (local) PR where we log a lot (coredns/coredns#3055) this triggers a data race

What did you expect to happen:
no data race.

Anything else you would like to add:
race triggered is:

WARNING: DATA RACE
Write at 0x000003b1be50 by goroutine 13:
  k8s.io/klog.SetOutput()
      /home/miek/g/pkg/mod/k8s.io/[email protected]/klog.go:743 +0xb8
  github.com/coredns/coredns/plugin/kubernetes.setup()
      /home/miek/go/coredns/coredns/plugin/kubernetes/setup.go:45 +0x6e
  github.com/caddyserver/caddy.executeDirectives()
      /home/miek/g/pkg/mod/github.com/caddyserver/[email protected]/caddy.go:665 +0x9ae
  github.com/caddyserver/caddy.ValidateAndExecuteDirectives()
      /home/miek/g/pkg/mod/github.com/caddyserver/[email protected]/caddy.go:621 +0x758
  github.com/caddyserver/caddy.startWithListenerFds()
      /home/miek/g/pkg/mod/github.com/caddyserver/[email protected]/caddy.go:516 +0x1b4
  github.com/caddyserver/caddy.Start()
      /home/miek/g/pkg/mod/github.com/caddyserver/[email protected]/caddy.go:473 +0x1ac
  github.com/coredns/coredns/test.TestReadme()
      /home/miek/go/coredns/coredns/test/readme_test.go:76 +0x4b3
  testing.tRunner()
      /home/miek/upstream/go/src/testing/testing.go:865 +0x163

Previous read at 0x000003b1be50 by goroutine 9:
  k8s.io/klog.(*loggingT).flushAll()
      /home/miek/g/pkg/mod/k8s.io/[email protected]/klog.go:1007 +0x72
  k8s.io/klog.(*loggingT).lockAndFlushAll()
      /home/miek/g/pkg/mod/k8s.io/[email protected]/klog.go:998 +0x51
  k8s.io/klog.(*loggingT).flushDaemon()
      /home/miek/g/pkg/mod/k8s.io/[email protected]/klog.go:991 +0x95

Make (also)logtostderr default to true

/kind feature

Describe the solution you'd like
I'd like to propose that logtostderr or alsologtostderr be defaulting to true. It's very common in the k8s community to have init() or main() functions to hardcode the flag to "true", flipping the default value of either flag should ease the use of this package and remove some initial friction for new users.

Anything else you would like to add:

Repeated trace in log file with error

/kind bug

What steps did you take and what happened:
https://play.golang.com/p/6l8KNG_iOsM

Configuring klog to write to a file and logtostderr=false, the log file is openned and wrote three times with the same content.

Removing the flush, writes three times the headers, but no content.

What did you expect to happen:
Only one open and write.

Anything else you would like to add:
[Miscellaneous information that will assist in solving the issue.]

-vmodule does not work for users of klogr interface

/kind bug

The -vmodule option works as expected where klog is used directly. However, where the the klog/klogr interface is used for logging, all such calls are treated as originating in klogr.go rather than the ultimate calling code.

What steps did you take and what happened:

package main

import (
    "errors"
    "flag"
    "github.com/go-logr/logr"
    "k8s.io/klog"
    "k8s.io/klog/klogr"
)

func main() {
    klog.InitFlags(nil)
    flag.Parse()

    var log logr.Logger
    log = klogr.New()
    log.V(0).Info("Info message.")
    log.V(1).Info("Info 1 message.")
    log.Error(errors.New("oops"), "Error.")
}
: logtest 112;  go build && ./logtest -vmodule main=1
I1112 17:02:45.832252   32339 main.go:46]  "msg"="Info message."  
E1112 17:02:45.832337   32339 main.go:48]  "msg"="Error." "error"="oops"  
: logtest 113;  go build && ./logtest -vmodule klogr=1
I1112 17:05:30.792956   32449 main.go:46]  "msg"="Info message."  
I1112 17:05:30.793030   32449 main.go:47]  "msg"="Info 1 message."  
E1112 17:05:30.793038   32449 main.go:48]  "msg"="Error." "error"="oops"  

What did you expect to happen:

: logtest 112;  go build && ./logtest -vmodule main=1
I1112 17:02:45.832252   32339 main.go:46]  "msg"="Info message."  
I1112 17:05:30.793030   32449 main.go:47]  "msg"="Info 1 message."  
E1112 17:02:45.832337   32339 main.go:48]  "msg"="Error." "error"="oops"  
: logtest 113;  go build && ./logtest -vmodule klogr=1
I1112 17:05:30.792956   32449 main.go:46]  "msg"="Info message."  
E1112 17:05:30.793038   32449 main.go:48]  "msg"="Error." "error"="oops"  

Anything else you would like to add:

From a casual review, this is probably an issue with klogr.go's framesToCaller() function.

Decrease flushInterval or make it configurable

/kind feature

Describe the solution you'd like
The current flushInterval is set to 30s, which is a lot higher than usually expected. It's common to adopt alternative strategies to flush more frequently. I'd be great to either decrease the default or make it configurable with a flag.

Anything else you would like to add:
[Miscellaneous information that will assist in solving the issue.]

Confusing arguments

/kind bug

What steps did you take and what happened:
It is kinda difficult to configure logging, as arguments don't work as expected.

Doc is outdated and still show glog:
https://godoc.org/k8s.io/klog

-logtostderr=false

But in code is defaulted to true:

flagset.BoolVar(&logging.toStderr, "logtostderr", true, "log to standard error instead of files")

Examples of weird behaviours.

No initialization shows >=error:

klog.Info("info")
klog.Error("error")

But if klog is initializated, it shows info and error (because flag logtostderr is set to true):

klog.InitFlags(nil)
flag.Parse()
klog.Info("info")
klog.Error("error")

Also weird because default value for stderrthreshold is ERROR and the doc says:

Log events at or above this severity are logged to standard error as well as to files

Then I switch off logging to stderr:

klog.InitFlags(nil)
flag.Set("logtostderr", "false")
flag.Parse()
klog.Info("info")
klog.Error("error")

And now it keeps logging to stderr but just error level.

What did you expect to happen:
Updated doc and a understandable behaviour.

Why not add "year" to log header or use well known time format?

/kind feature

Describe the solution you'd like
[A clear and concise description of what you want to happen.]

klog/klog.go

Line 622 in 3ca30a5

_, month, day := now.Date()

Currently, the log header does not contain "year" info, so we cannot get the absolute time of each log line.
For example, we meet some problems:

  1. We cannot distingush "I0809" is 2019/08/09 or 2018/08/09 when debugging
  2. If the log is sinked to elastic search, and given 2 entries which is extracted from 2 log lines "I0101" and "I1231", we cannot know which entry is the latest entry (i.e. the one with the largest timestamp).
  3. 3rd log collector, such as docker or fluentd can append timestamp to each log line, but the collected timestamp is not so accurate as the logged timestamp. And this make klog hard depends on 3rd collector.

It is too uncommon to discard year but leave other timestamp in the log header.
So I hope if we can add the year to log header?

Moreover, can we use well known time format in log header, such as these in the Golang time package:
https://github.com/golang/go/blob/1dc0110bf725640a9b912e3d31e6654ed1c4da9d/src/time/format.go#L83

Anything else you would like to add:
[Miscellaneous information that will assist in solving the issue.]

Better docs/code for glog co-existence

/kind feature

Describe the solution you'd like

I think, given klog has essentially the same semantics as glog and the simplicity of the solution, this wrapper solution should be made official. The existing "co-exist with glog" suggestion has at least the one shortcoming of flags only being synced once.

I'm willing to do the work (mostly just document it) if you believe this is a good solution.

document differences vs glog

Can we put a TLDR somewhere of things we've fixed or improved vs glog? I think it would be helpful for other ecosystem projects.

cc @dims

Flag log_dir not work

/kind bug

What steps did you take and what happened:
[A clear and concise description of what the bug is.]
main.go

package main

import (
	"k8s.io/klog"
)

func main() {
	klog.InitFlags(nil)
	klog.Info("start")
	klog.Flush()
}

go build -o main main.go
mkdir logs
./main -logtostderr=false -log_dir=logs

There is no log files under the dir "logs".

What did you expect to happen:
There are some files in the dir "logs"

remove os.Exit from this package

/kind feature

klog inherits calling os.Exit from glog when things go sour. This is bad behaviour for a go library. As an application writer I don't want to beholden to klog deciding that my app needs to be killed.

Can this be behaviour be removed from this library?

Ability to set log format

/kind feature

Currently, klog V2 writes log with a prefix in front of it as shown below. But the issue is that I run my apps in Google Kubernetes Engine and I use GCP StackDriver Logging which requires you to send a JSON format log to it. But klog (and glog) attach the prefix to it which breaks the JSON message. So GCP StackDriver Logging picks up all log statements as INFO even if I mark them for DEBUG, ERROR, and such in the serverity field.

So if I had the ability to set my own log format when the flags are being set, I could easily fix this issue.

Current log statment
I0511 13:00:37.193484 1 logger.go:63] {"severity":"INFO", "message":"app started"}

Preferred log statement
{"severity":"INFO", "message":"app started"}

Why klog?

/kind bug

It would be nice for the README file for klog to explain why the fork, versus contributing to glog.

Difficult to configure logging to file

Similar to #54, but in order to configure logging to a file and to stderr, we must first turn off logtostderr.

--logtostderr=false --alsologtostderr --log-file=my.log

I'm thinking that the logic for logging needs to be changed to reflect the changed default for logtostderr; I think a non-empty log-file should result in us not logging to stderr, unless alsologtostderr is true.

/kind bug

running klog as a dependency causes `read-only filesystem` errors

/kind bug

What steps did you take and what happened:

Running a pod on Kube which has klog as an implicit dependency. Crashes on boot with log: exiting because of error: log: cannot create log: open /tmp/gloo.gloo-7cbdc7dd4f-btkps.unknownuser.log.WARNING.20190813-140027.1: read-only file system

Would like to know if there is a way to disable Klog from writing to disk?

update SetOutput example

klog.SetOutput is a bit of a footgun right now, severities above INFO will write to the "files" with fallthrough to the lower files, potentially leading to the same line being written as many as 4 times to the same writer.

I think the safest usage of this right now is probably something like:

klog.SetOutput(ioutil.Discard)
klog.SetOutputBySeverity("INFO", myWriter)

This works pretty nicely, but probably need some more documentation. I initially just did:

klog.SetOutput(myWriter)

which has surprising (duplicated) output in some cases

Default behaviour changes when InitFlags is called

When InitFlags is called (or technically flag.Parse), the default behavior changes. toStderr=true and logFileMaxSizeMB=1800 are only set when InitFlags is used.

This makes the library behaviour difficult to predict.

/kind bug

klog.SetOutput(ioutil.Discard) doesn't remove output

/kind bug

What steps did you take and what happened:
calling klog.SetOutput(ioutil.Discard doesn't remove logging output.

What did you expect to happen:
No logging ouput.

Anything else you would like to add:
In coredns/coredns#3055 I want to test various things, but not clutter the output to much, so I call klog.SetOutput(ioutil.Discard), but the screen this is full off:

0810 07:23:54.827224    2826 reflector.go:126] pkg/mod/k8s.io/[email protected]+incompatible/tools/cache/reflector.go:94: Failed to list *v1.Pod: Get https://127.0.0.1:443/api/v1/pods?fieldSelector=status.phase%21%3DSucceeded%2Cstatus.phase%21%3DFailed%2Cstatus.phase%21%3DUnknown&limit=500&resourceVersion=0: dial tcp 127.0.0.1:443: connect: connection refused
E0810 07:23:54.827224    2826 reflector.go:126] pkg/mod/k8s.io/[email protected]+incompatible/tools/cache/reflector.go:94: Failed to list *v1.Pod: Get https://127.0.0.1:443/api/v1/pods?fieldSelector=status.phase%21%3DSucceeded%2Cstatus.phase%21%3DFailed%2Cstatus.phase%21%3DUnknown&limit=500&resourceVersion=0: dial tcp 127.0.0.1:443: connect: connection refused
E0810 07:23:54.827224    2826 reflector.go:126] pkg/mod/k8s.io/[email protected]+incompatible/tools/cache/reflector.go:94: Failed to list *v1.Pod: Get https://127.0.0.1:443/api/v1/pods?fieldSelector=status.phase%21%3DSucceeded%2Cstatus.phase%21%3DFailed%2Cstatus.phase%21%3DUnknown&limit=500&resourceVersion=0: dial tcp 127.0.0.1:443: connect: connection refused
E0810 07:23:54.827224    2826 reflector.go:126] pkg/mod/k8s.io/[email protected]+incompatible/tools/cache/reflector.go:94: Failed to list *v1.Pod: Get https://127.0.0.1:443/api/v1/pods?fieldSelector=status.phase%21%3DSucceeded%2Cstatus.phase%21%3DFailed%2Cstatus.phase%21%3DUnknown&limit=500&resourceVersion=0: dial tcp 127.0.0.1:443: connect: connection refused
E0810 07:23:54.829765    2826 reflector.go:126] pkg/mod/k8s.io/[email protected]+incompatible/tools/cache/reflector.go:94: Failed to list *v1.Pod: Get https://127.0.0.1:443/api/v1/pods?fieldSelector=status.phase%21%3DSucceeded%2Cstatus.phase%21%3DFailed%2Cstatus.phase%21%3DUnknown&limit=500&resourceVersion=0: dial tcp 127.0.0.1:443: connect: connection refused
E0810 07:23:54.829765    2826 reflector.go:126] pkg/mod/k8s.io/[email protected]+incompatible/tools/cache/reflector.go:94: Failed to list *v1.Pod: Get https://127.0.0.1:443/api/v1/pods?fieldSelector=status.phase%21%3DSucceeded%2Cstatus.phase%21%3DFailed%2Cstatus.phase%21%3DUnknown&limit=500&resourceVersion=0: dial tcp 127.0.0.1:443: connect: connection refused
E0810 07:23:54.829765    2826 reflector.go:126] pkg/mod/k8s.io/[email protected]+incompatible/tools/cache/reflector.go:94: Failed to list *v1.Pod: Get https://127.0.0.1:443/api/v1/pods?fieldSelector=status.phase%21%3DSucceeded%2Cstatus.phase%21%3DFailed%2Cstatus.phase%21%3DUnknown&limit=500&resourceVersion=0: dial tcp 127.0.0.1:443: connect: connection refused
E0810 07:23:54.829765    2826 reflector.go:126] pkg/mod/k8s.io/[email protected]+incompatible/tools/cache/reflector.go:94: Failed to list *v1.Pod: Get https://127.0.0.1:443/api/v1/pods?fieldSelector=status.phase%21%3DSucceeded%2Cstatus.phase%21%3DFailed%2Cstatus.phase%21%3DUnknown&limit=500&resourceVersion=0: dial tcp 127.0.0.1:443: connect: connection refused
~~~

Cleanup codes glued to logging global variable

/kind cleanup

Describe the solution you'd like
In klog, there is codes glued to logging global variable. e.g. :

  • output method of loggingT
    As explained in #116 , logging.logFile is used in this method, not l.logFile. And because create function in klog_file.go refers to logging.logFile, this method is glued to global variable logging.

I think it's better to cleanup those code if possible.

klog adds additional global flags

What steps did you take and what happened:
klog 0.3.0 added a new global flag (--log_file_max_size). Global flags behave poorly in the presence of conflicting flags, or when a single binary links in multiple commands.

What did you expect to happen:
klog to provide an AddFlags(flagSet)-style mechanism for registering flags into a non-global flagset, rather than continuing to expand global flag registration in a way all downstream consumers have to react to.

After klog v2.0.0 release there are broken dependencies

/kind bug

What steps did you take and what happened:
after running dep ensure -update -v in a go project I get the following:

Solving failure: No versions of k8s.io/utils met constraints:
	master: Could not introduce k8s.io/utils@master, as it requires package k8s.io/klog/v2 from k8s.io/klog, but in version v2.0.0 that package is missing.
	godocs-readme: Could not introduce k8s.io/utils@godocs-readme due to multiple problematic subpackages:
	Subpackage k8s.io/utils/buffer is missing. (Package is required by k8s.io/[email protected].)	Subpackage k8s.io/utils/integer is missing. (Package is required by k8s.io/[email protected].)	Subpackage k8s.io/utils/trace is missing. (Package is required by k8s.io/[email protected].)

What did you expect to happen:
Having import "k8s.io/klog/v2" keep working as it is still used widely

Anything else you would like to add:
I see many projects still use k8s.io/klog/v2 endpoint in their source for klog v2. It would be nice to keep it for backward compatibility.

Call to user.Current() crashes on Windows Nano

/kind bug

What steps did you take and what happened:
The init function in klog_file.go [1] uses a Go API that doesn't work on Windows Nano [2], making every program that depends on klog crash on this platform. Note also that k8s is a primary target of Windows Nano, so this can be a common case.

What did you expect to happen:
This might eventually get fixed on Go's side, but since the issue [1] has been open for 3 years now it might be worth implementing a workaround on klog.

[1] golang/go#21867
[2] https://github.com/kubernetes/klog/blob/master/klog_file.go#L58

Documentation for `V()` appears to be backwards

/kind bug

What steps did you take and what happened:
Read the documentation and got confused by how V() works.

It says (for 2.0.0):

If the level in the call to V is at least the value of -v, […] the V call will log.

This says that when the application is invoked with -v 3, then V(4) will log but V(2) will not.

The code actually says:

if logging.verbosity.get() >= level { … do logging … }

The is the opposite (-v is at least the value of V()), and is the typical interpretation for verbosity levels.

What did you expect to happen:

Given that the documentation says at least, I would expect that V(n) will log if n is greater than the value given on the command line.

Anything else you would like to add:
This appears to be carried over from glog. Comparing against the C++ glog, that instead is documented from the other side; it has:

v (int, default=0)
Show all VLOG(m) messages for m less or equal the value of this flag. Overridable by --vmodule.

Given the age of the comment, perhaps I'm just reading it weird? It may be a good idea to at least add examples to disambiguate the situation.

I'm happy to make a PR if people agree this is a thing that should be changed.

InitFlags does not reset klog configuration if application already did logging

/kind bug

What steps did you take and what happened:

  1. Application uses klog.Infof()
  2. Logging happens based on klog default configuration.
  3. Application calls klog.InitFlags(nil) and flag.Parse(). Flags specify log file.
  4. Application uses klog.Infof() again.
  5. Logs are NOT appended to output file specified by flags

What did you expect to happen:

Ideally klog should properly reinitialize itself to configuration specified via flags on (4) and log from (5) should be appended to the log file.

Alternatively klog could disallows calling InitFlag() after logging was done before (panic?).
Yet this is suboptimal as one not always can prevent logging from happening before InitFlags. As logging can occur in init function of some dependent module.

Anything else you would like to add:

The source of described problem lies in behavior of createFiles (https://github.com/kubernetes/klog/blob/master/klog.go#L968). This method is called on first logging and log appenders are created then and put in logging.files array. Those are not reset later even if configuration changes.

Actually the situation is even more confusing than that. As appenders are created only for log levels up to requested one, we end up in inconsistent state of klog in following sequence of events:

  1. klog.Infof
  2. InitFlags
  3. klog.ErrorF

Then the appenders for DEBUG and INFO will be based on default configuration. And appender for ERROR will take configuration changes from flags into account.

I spotted the problem when playing with flag related to log file but possibly one can run into issues with other flags too.

Child loggers

/kind feature

Describe the solution you'd like
A common use case for loggers is to provide a default context. An example is to prepend some common values to each log line. I've seen other loggers are able to create a child logger of some sort with a predefined set of variables which are used as suffix for each log line.

I'd imagine this approach to have some sort of limitations, for example how many variables are allowed to be set as context. This approach would have the following requirements:

  • The global logger has a 1 to many relationship with many child loggers.
  • Child loggers have only have a single parent.
  • No hard to debug multi-layer nested loggers.
  • Sinks (re: #19) are only managed at the global logger.

Thoughts?

Provide example how to use dep override for glog proxy

/kind feature

I tried to add to my Godep.toml next lines

[[override]]
    name = "github.com/golang/glog"
    source = "k8s.io/klog/glog"

but apparently dep ignored the /glog suffix and copied entire klog into vendor/github.com/golang/glog. And it looks dep's authors don't want to have subdirs.

As dep is mentioned in the README file, I expect there should be a way to do it, though.

Make type loggingT public type

/kind feature

Describe the solution you'd like
[A clear and concise description of what you want to happen.]
I would like to make type loggingT public type. Because I want to make importer of klog be able to handle multiple logr.InfoLogger & logr.Logger.

Anything else you would like to add:
[Miscellaneous information that will assist in solving the issue.]

  • Make loggingT public type
  • Modify code glued to logging global variable (e.g. method setVState of loggingT: it only refers to global variable logging) & add function/method to maintain backward compatibility.

Credential redaction or generic output filters

/kind feature

Describe the solution you'd like
The goal is to prevent accidental logging of credentials.
Ideally this would be opt-out output filter for things that look like:

  • JWT
  • PEM-encoded private key
  • bearer tokens

Filter would replace these with something like --- REDACTED CREDENTIAL ---.

Alternatively, allow arbitrary pluggable filters, something like:

func AddFilter(filter func(line string) string)

Anything else you would like to add:
Performance impact would be the main concern here.

cc @mikedanese @liggitt

Implement klog.KObj klog.KRef functions

/kind feature

Describe the solution you'd like
Klog should implement standard klog.KObj and klog.KRef functions needed for referencing kubernetes objects.

func KObj(obj ObjectMeta) ObjectRef
func KRef(namespace, name string) ObjectRef

type ObjectRef struct {
  Name      string `json:"name"`
  Namespace string `json:"namespace,omitempty"`
}

Specifications are described within KEP

Anything else you would like to add:
Part of Structured Logging effort kubernetes/enhancements#1602
/help
/priority important-soon
/sig instrumentation
/milestone v1.19

Add VDepth()

/kind feature

Describe the solution you'd like
We're trying to have a simple wrapper around klog package.
Currently klog.V() uses a hard-coded call depth when checking vmodule in V()
(https://github.com/kubernetes/klog/blob/master/klog.go#L1203), which prevents wrapping of klog.V().

It would be great to allow this kind of wrapping by adding VDepth(depth int, level Level) like InfoDepth().

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.