func InitFlags(flagset *flag.FlagSet) {
	initDefaultsOnce.Do(func() {
		logging.logDir = ""
		logging.logFile = ""
		logging.logFileMaxSizeMB = 1800
		logging.toStderr = true
		logging.alsoToStderr = false
		logging.skipHeaders = false
		logging.skipLogHeaders = false
	})
	if flagset == nil {
		flagset = flag.CommandLine
	}
	flagset.StringVar(&logging.logDir, "log_dir", logging.logDir, "If non-empty, write log files in this directory")
	flagset.StringVar(&logging.logFile, "log_file", logging.logFile, "If non-empty, use this log file")
	flagset.Uint64Var(&logging.logFileMaxSizeMB, "log_file_max_size", logging.logFileMaxSizeMB,
		"Defines the maximum size a log file can grow to. Unit is megabytes. "+
			"If the value is 0, the maximum file size is unlimited.")
	flagset.BoolVar(&logging.toStderr, "logtostderr", logging.toStderr, "log to standard error instead of files")
	flagset.BoolVar(&logging.alsoToStderr, "alsologtostderr", logging.alsoToStderr, "log to standard error as well as files")
	flagset.Var(&logging.verbosity, "v", "number for the log level verbosity")
	flagset.BoolVar(&logging.skipHeaders, "skip_headers", logging.skipHeaders, "If true, avoid header prefixes in the log messages")
	flagset.BoolVar(&logging.skipLogHeaders, "skip_log_headers", logging.skipLogHeaders, "If true, avoid headers when opening log files")
	flagset.Var(&logging.stderrThreshold, "stderrthreshold", "logs at or above this threshold go to stderr")
	flagset.Var(&logging.vmodule, "vmodule", "comma-separated list of pattern=N settings for file-filtered logging")
	flagset.Var(&logging.traceLocation, "log_backtrace_at", "when logging hits line file:N, emit a stack trace")
}
InitFlags is for explicitly initializing the flags.
package klog
import (
	"bufio"
	"bytes"
	"errors"
	"flag"
	"fmt"
	"io"
	stdLog "log"
	"math"
	"os"
	"path/filepath"
	"runtime"
	"strconv"
	"strings"
	"sync"
	"sync/atomic"
	"time"
)
type severity int32  
const (
	infoLog severity = iota
	warningLog
	errorLog
	fatalLog
	numSeverity = 4
)
const severityChar = "IWEF"
var severityName = []string{
	infoLog:    "INFO",
	warningLog: "WARNING",
	errorLog:   "ERROR",
	fatalLog:   "FATAL",
}
func (s *severity) get() severity {
	return severity(atomic.LoadInt32((*int32)(s)))
}
func (s *severity) set(val severity) {
	atomic.StoreInt32((*int32)(s), int32(val))
}
func (s *severity) String() string {
	return strconv.FormatInt(int64(*s), 10)
}
func (s *severity) Get() interface{} {
	return *s
}
func (s *severity) Set(value string) error {
	var threshold severity
	if v, ok := severityByName(value); ok {
		threshold = v
	} else {
		v, err := strconv.Atoi(value)
		if err != nil {
			return err
		}
		threshold = severity(v)
	}
	logging.stderrThreshold.set(threshold)
	return nil
}
func severityByName(s string) (severity, bool) {
	s = strings.ToUpper(s)
	for i, name := range severityName {
		if name == s {
			return severity(i), true
		}
	}
	return 0, false
}
type OutputStats struct {
	lines int64
	bytes int64
}
func (s *OutputStats) Lines() int64 {
	return atomic.LoadInt64(&s.lines)
}
func (s *OutputStats) Bytes() int64 {
	return atomic.LoadInt64(&s.bytes)
}
var Stats struct {
	Info, Warning, Error OutputStats
}
var severityStats = [numSeverity]*OutputStats{
	infoLog:    &Stats.Info,
	warningLog: &Stats.Warning,
	errorLog:   &Stats.Error,
}
type Level int32
func (l *Level) get() Level {
	return Level(atomic.LoadInt32((*int32)(l)))
}
func (l *Level) set(val Level) {
	atomic.StoreInt32((*int32)(l), int32(val))
}
func (l *Level) String() string {
	return strconv.FormatInt(int64(*l), 10)
}
func (l *Level) Get() interface{} {
	return *l
}
func (l *Level) Set(value string) error {
	v, err := strconv.Atoi(value)
	if err != nil {
		return err
	}
	logging.mu.Lock()
	defer logging.mu.Unlock()
	logging.setVState(Level(v), logging.vmodule.filter, false)
	return nil
}
type moduleSpec struct {
	filter []modulePat
}
type modulePat struct {
	pattern string
	literal bool  
	level   Level
}
func (m *modulePat) match(file string) bool {
	if m.literal {
		return file == m.pattern
	}
	match, _ := filepath.Match(m.pattern, file)
	return match
}
func (m *moduleSpec) String() string {
	logging.mu.Lock()
	defer logging.mu.Unlock()
	var b bytes.Buffer
	for i, f := range m.filter {
		if i > 0 {
			b.WriteRune(',')
		}
		fmt.Fprintf(&b, "%s=%d", f.pattern, f.level)
	}
	return b.String()
}
func (m *moduleSpec) Get() interface{} {
	return nil
}
var errVmoduleSyntax = errors.New("syntax error: expect comma-separated list of filename=N")
func (m *moduleSpec) Set(value string) error {
	var filter []modulePat
	for _, pat := range strings.Split(value, ",") {
		if len(pat) == 0 {
			continue
		}
		patLev := strings.Split(pat, "=")
		if len(patLev) != 2 || len(patLev[0]) == 0 || len(patLev[1]) == 0 {
			return errVmoduleSyntax
		}
		pattern := patLev[0]
		v, err := strconv.Atoi(patLev[1])
		if err != nil {
			return errors.New("syntax error: expect comma-separated list of filename=N")
		}
		if v < 0 {
			return errors.New("negative value for vmodule level")
		}
		if v == 0 {
			continue  
		}
		filter = append(filter, modulePat{pattern, isLiteral(pattern), Level(v)})
	}
	logging.mu.Lock()
	defer logging.mu.Unlock()
	logging.setVState(logging.verbosity, filter, true)
	return nil
}
func isLiteral(pattern string) bool {
	return !strings.ContainsAny(pattern, `\*?[]`)
}
type traceLocation struct {
	file string
	line int
}
func (t *traceLocation) isSet() bool {
	return t.line > 0
}
func (t *traceLocation) match(file string, line int) bool {
	if t.line != line {
		return false
	}
	if i := strings.LastIndex(file, "/"); i >= 0 {
		file = file[i+1:]
	}
	return t.file == file
}
func (t *traceLocation) String() string {
	logging.mu.Lock()
	defer logging.mu.Unlock()
	return fmt.Sprintf("%s:%d", t.file, t.line)
}
func (t *traceLocation) Get() interface{} {
	return nil
}
var errTraceSyntax = errors.New("syntax error: expect file.go:234")
func (t *traceLocation) Set(value string) error {
	if value == "" {
		t.line = 0
		t.file = ""
	}
	fields := strings.Split(value, ":")
	if len(fields) != 2 {
		return errTraceSyntax
	}
	file, line := fields[0], fields[1]
	if !strings.Contains(file, ".") {
		return errTraceSyntax
	}
	v, err := strconv.Atoi(line)
	if err != nil {
		return errTraceSyntax
	}
	if v <= 0 {
		return errors.New("negative or zero value for level")
	}
	logging.mu.Lock()
	defer logging.mu.Unlock()
	t.line = v
	t.file = file
	return nil
}
type flushSyncWriter interface {
	Flush() error
	Sync() error
	io.Writer
}
func init() {
	logging.stderrThreshold = errorLog
	logging.setVState(0, nil, false)
	go logging.flushDaemon()
}
var initDefaultsOnce sync.Once