Clean up logging using glogr
This commit is contained in:
parent
ff73d8e4f0
commit
dd60fb0312
|
|
@ -0,0 +1,22 @@
|
||||||
|
{
|
||||||
|
"ImportPath": "k8s.io/git-sync",
|
||||||
|
"GoVersion": "go1.6",
|
||||||
|
"GodepVersion": "v66",
|
||||||
|
"Packages": [
|
||||||
|
"./..."
|
||||||
|
],
|
||||||
|
"Deps": [
|
||||||
|
{
|
||||||
|
"ImportPath": "github.com/golang/glog",
|
||||||
|
"Rev": "23def4e6c14b4da8ac2ed8007337bc5eb5007998"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "github.com/thockin/glogr",
|
||||||
|
"Rev": "7a7f3ced4f9f52e96710761820bd85ed6c400aa5"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "github.com/thockin/logr",
|
||||||
|
"Rev": "103d90809f342ce8b186c0bc903a34bc1c8007be"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
This directory tree is generated automatically by godep.
|
||||||
|
|
||||||
|
Please do not edit.
|
||||||
|
|
||||||
|
See https://github.com/tools/godep for more information.
|
||||||
5
Makefile
5
Makefile
|
|
@ -32,7 +32,6 @@ KUBE_CROSS_VERSION ?= v1.6.3-2
|
||||||
|
|
||||||
GO_PKG = k8s.io/git-sync
|
GO_PKG = k8s.io/git-sync
|
||||||
BIN = git-sync
|
BIN = git-sync
|
||||||
SRCS = main.go
|
|
||||||
|
|
||||||
# If you want to build all containers, see the 'all-container' rule.
|
# If you want to build all containers, see the 'all-container' rule.
|
||||||
# If you want to build AND push all containers, see the 'all-push' rule.
|
# If you want to build AND push all containers, see the 'all-push' rule.
|
||||||
|
|
@ -52,7 +51,7 @@ all-push: $(addprefix sub-push-,$(ALL_ARCH))
|
||||||
|
|
||||||
build: bin/$(BIN)-$(ARCH)
|
build: bin/$(BIN)-$(ARCH)
|
||||||
|
|
||||||
bin/$(BIN)-$(ARCH): $(SRCS)
|
bin/$(BIN)-$(ARCH): FORCE
|
||||||
mkdir -p bin
|
mkdir -p bin
|
||||||
docker run \
|
docker run \
|
||||||
-u $$(id -u):$$(id -g) \
|
-u $$(id -u):$$(id -g) \
|
||||||
|
|
@ -87,3 +86,5 @@ endif
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -rf .container-* .push-* bin/
|
rm -rf .container-* .push-* bin/
|
||||||
|
|
||||||
|
FORCE:
|
||||||
|
|
|
||||||
82
main.go
82
main.go
|
|
@ -24,7 +24,6 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"log"
|
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
|
|
@ -33,6 +32,9 @@ import (
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/thockin/glogr"
|
||||||
|
"github.com/thockin/logr"
|
||||||
)
|
)
|
||||||
|
|
||||||
var flRepo = flag.String("repo", envString("GIT_SYNC_REPO", ""), "git repo url")
|
var flRepo = flag.String("repo", envString("GIT_SYNC_REPO", ""), "git repo url")
|
||||||
|
|
@ -59,6 +61,17 @@ var flPassword = flag.String("password", envString("GIT_SYNC_PASSWORD", ""), "pa
|
||||||
|
|
||||||
var flSSH = flag.Bool("ssh", envBool("GIT_SYNC_SSH", false), "use SSH protocol")
|
var flSSH = flag.Bool("ssh", envBool("GIT_SYNC_SSH", false), "use SSH protocol")
|
||||||
|
|
||||||
|
var log = newLoggerOrDie()
|
||||||
|
|
||||||
|
func newLoggerOrDie() logr.Logger {
|
||||||
|
g, err := glogr.New()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Fprintf(os.Stderr, "failind to initialize logging: %v", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
return g
|
||||||
|
}
|
||||||
|
|
||||||
func envString(key, def string) string {
|
func envString(key, def string) string {
|
||||||
if env := os.Getenv(key); env != "" {
|
if env := os.Getenv(key); env != "" {
|
||||||
return env
|
return env
|
||||||
|
|
@ -82,7 +95,7 @@ func envInt(key string, def int) int {
|
||||||
if env := os.Getenv(key); env != "" {
|
if env := os.Getenv(key); env != "" {
|
||||||
val, err := strconv.Atoi(env)
|
val, err := strconv.Atoi(env)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("invalid value for %q: using default: %q", key, def)
|
log.Errorf("invalid value for %q: using default: %q", key, def)
|
||||||
return def
|
return def
|
||||||
}
|
}
|
||||||
return val
|
return val
|
||||||
|
|
@ -90,29 +103,29 @@ func envInt(key string, def int) int {
|
||||||
return def
|
return def
|
||||||
}
|
}
|
||||||
|
|
||||||
const usage = "usage: GIT_SYNC_REPO= GIT_SYNC_DEST= [GIT_SYNC_BRANCH= GIT_SYNC_WAIT= GIT_SYNC_DEPTH= GIT_SYNC_USERNAME= GIT_SYNC_PASSWORD= GIT_SYNC_SSH= GIT_SYNC_ONE_TIME= GIT_SYNC_MAX_SYNC_FAILURES=] git-sync -repo GIT_REPO_URL -dest PATH [-branch -wait -username -password -ssh -depth -one-time -max-sync-failures]"
|
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
setFlagDefaults()
|
||||||
|
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
if *flRepo == "" || *flDest == "" {
|
if *flRepo == "" || *flDest == "" {
|
||||||
flag.Usage()
|
flag.Usage()
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
if _, err := exec.LookPath("git"); err != nil {
|
if _, err := exec.LookPath("git"); err != nil {
|
||||||
log.Printf("required git executable not found: %v", err)
|
log.Errorf("required git executable not found: %v", err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
if *flUsername != "" && *flPassword != "" {
|
if *flUsername != "" && *flPassword != "" {
|
||||||
if err := setupGitAuth(*flUsername, *flPassword, *flRepo); err != nil {
|
if err := setupGitAuth(*flUsername, *flPassword, *flRepo); err != nil {
|
||||||
log.Printf("error creating .netrc file: %v", err)
|
log.Errorf("error creating .netrc file: %v", err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if *flSSH {
|
if *flSSH {
|
||||||
if err := setupGitSSH(); err != nil {
|
if err := setupGitSSH(); err != nil {
|
||||||
log.Printf("error configuring SSH: %v", err)
|
log.Errorf("error configuring SSH: %v", err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -122,22 +135,22 @@ func main() {
|
||||||
for {
|
for {
|
||||||
if err := syncRepo(*flRepo, *flBranch, *flRev, *flDepth, *flRoot, *flDest); err != nil {
|
if err := syncRepo(*flRepo, *flBranch, *flRev, *flDepth, *flRoot, *flDest); err != nil {
|
||||||
if initialSync || failCount >= *flMaxSyncFailures {
|
if initialSync || failCount >= *flMaxSyncFailures {
|
||||||
log.Printf("error syncing repo: %v", err)
|
log.Errorf("error syncing repo: %v", err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
failCount++
|
failCount++
|
||||||
log.Printf("unexpected error syncing repo: %v", err)
|
log.Errorf("unexpected error syncing repo: %v", err)
|
||||||
log.Printf("waiting %d seconds before retryng", *flWait)
|
log.V(0).Infof("waiting %d seconds before retryng", *flWait)
|
||||||
time.Sleep(time.Duration(*flWait) * time.Second)
|
time.Sleep(time.Duration(*flWait) * time.Second)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if initialSync {
|
if initialSync {
|
||||||
if isHash, err := revIsHash(*flRev, *flRoot); err != nil {
|
if isHash, err := revIsHash(*flRev, *flRoot); err != nil {
|
||||||
log.Printf("can't tell if rev %s is a git hash, exiting", *flRev)
|
log.Errorf("can't tell if rev %s is a git hash, exiting", *flRev)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
} else if isHash {
|
} else if isHash {
|
||||||
log.Printf("rev %s appears to be a git hash, no further sync needed", *flRev)
|
log.V(0).Infof("rev %s appears to be a git hash, no further sync needed", *flRev)
|
||||||
sleepForever()
|
sleepForever()
|
||||||
}
|
}
|
||||||
if *flOneTime {
|
if *flOneTime {
|
||||||
|
|
@ -147,11 +160,21 @@ func main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
failCount = 0
|
failCount = 0
|
||||||
log.Printf("next sync in %d seconds", *flWait)
|
log.V(0).Infof("next sync in %d seconds", *flWait)
|
||||||
time.Sleep(time.Duration(*flWait) * time.Second)
|
time.Sleep(time.Duration(*flWait) * time.Second)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func setFlagDefaults() {
|
||||||
|
// Force logging to stderr.
|
||||||
|
stderrFlag := flag.Lookup("logtostderr")
|
||||||
|
if stderrFlag == nil {
|
||||||
|
fmt.Fprintf(os.Stderr, "can't find flag 'logtostderr'")
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
stderrFlag.Value.Set("true")
|
||||||
|
}
|
||||||
|
|
||||||
// Do no work, but don't do something that triggers go's runtime into thinking
|
// Do no work, but don't do something that triggers go's runtime into thinking
|
||||||
// it is deadlocked.
|
// it is deadlocked.
|
||||||
func sleepForever() {
|
func sleepForever() {
|
||||||
|
|
@ -179,12 +202,12 @@ func updateSymlink(gitRoot, link, newDir string) error {
|
||||||
if _, err := runCommand(gitRoot, "ln", "-snf", newDirRelative, "tmp-link"); err != nil {
|
if _, err := runCommand(gitRoot, "ln", "-snf", newDirRelative, "tmp-link"); err != nil {
|
||||||
return fmt.Errorf("error creating symlink: %v", err)
|
return fmt.Errorf("error creating symlink: %v", err)
|
||||||
}
|
}
|
||||||
log.Printf("created symlink %s -> %s", "tmp-link", newDirRelative)
|
log.V(1).Infof("created symlink %s -> %s", "tmp-link", newDirRelative)
|
||||||
|
|
||||||
if _, err := runCommand(gitRoot, "mv", "-T", "tmp-link", link); err != nil {
|
if _, err := runCommand(gitRoot, "mv", "-T", "tmp-link", link); err != nil {
|
||||||
return fmt.Errorf("error replacing symlink: %v", err)
|
return fmt.Errorf("error replacing symlink: %v", err)
|
||||||
}
|
}
|
||||||
log.Printf("renamed symlink %s to %s", "tmp-link", link)
|
log.V(1).Infof("renamed symlink %s to %s", "tmp-link", link)
|
||||||
|
|
||||||
// Clean up previous worktree
|
// Clean up previous worktree
|
||||||
if len(currentDir) > 0 {
|
if len(currentDir) > 0 {
|
||||||
|
|
@ -192,14 +215,14 @@ func updateSymlink(gitRoot, link, newDir string) error {
|
||||||
return fmt.Errorf("error removing directory: %v", err)
|
return fmt.Errorf("error removing directory: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Printf("removed %s", currentDir)
|
log.V(1).Infof("removed %s", currentDir)
|
||||||
|
|
||||||
_, err := runCommand(gitRoot, "git", "worktree", "prune")
|
_, err := runCommand(gitRoot, "git", "worktree", "prune")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Printf("pruned old worktrees")
|
log.V(1).Infof("pruned old worktrees")
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|
@ -213,7 +236,6 @@ func addWorktreeAndSwap(gitRoot, dest, branch, rev string) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
log.Printf("fetched origin/%s", branch)
|
|
||||||
|
|
||||||
// Find the real commit for the rev.
|
// Find the real commit for the rev.
|
||||||
output, err := runCommand(gitRoot, "git", "rev-list", "-n1", rev)
|
output, err := runCommand(gitRoot, "git", "rev-list", "-n1", rev)
|
||||||
|
|
@ -222,7 +244,7 @@ func addWorktreeAndSwap(gitRoot, dest, branch, rev string) error {
|
||||||
}
|
}
|
||||||
revhash := strings.Trim(string(output), "\n")
|
revhash := strings.Trim(string(output), "\n")
|
||||||
if revhash != rev {
|
if revhash != rev {
|
||||||
log.Printf("rev %s resolves to %s", rev, revhash)
|
log.V(0).Infof("rev %s resolves to %s", rev, revhash)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make a worktree for this exact git hash.
|
// Make a worktree for this exact git hash.
|
||||||
|
|
@ -231,7 +253,7 @@ func addWorktreeAndSwap(gitRoot, dest, branch, rev string) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
log.Printf("added worktree %s for origin/%s", worktreePath, branch)
|
log.V(0).Infof("added worktree %s for origin/%s", worktreePath, branch)
|
||||||
|
|
||||||
// The .git file in the worktree directory holds a reference to
|
// The .git file in the worktree directory holds a reference to
|
||||||
// /git/.git/worktrees/<worktree-dir-name>. Replace it with a reference
|
// /git/.git/worktrees/<worktree-dir-name>. Replace it with a reference
|
||||||
|
|
@ -251,7 +273,7 @@ func addWorktreeAndSwap(gitRoot, dest, branch, rev string) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
log.Printf("reset worktree %s to %s", worktreePath, rev)
|
log.V(0).Infof("reset worktree %s to %s", worktreePath, rev)
|
||||||
|
|
||||||
if *flChmod != 0 {
|
if *flChmod != 0 {
|
||||||
// set file permissions
|
// set file permissions
|
||||||
|
|
@ -274,7 +296,7 @@ func cloneRepo(repo, branch, rev string, depth int, gitRoot string) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
log.Printf("cloned %s", repo)
|
log.V(0).Infof("cloned %s", repo)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
@ -310,9 +332,9 @@ func syncRepo(repo, branch, rev string, depth int, gitRoot, dest string) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if needed {
|
if needed {
|
||||||
log.Printf("update required")
|
log.V(0).Infof("update required")
|
||||||
} else {
|
} else {
|
||||||
log.Printf("no update required")
|
log.V(0).Infof("no update required")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -330,7 +352,7 @@ func needResync(localDir, rev string) (bool, error) {
|
||||||
local = strings.Trim(local, "\n")
|
local = strings.Trim(local, "\n")
|
||||||
|
|
||||||
// Fetch rev from upstream.
|
// Fetch rev from upstream.
|
||||||
_, err := runCommand(localDir, "git", "fetch", "origin", rev)
|
_, err = runCommand(localDir, "git", "fetch", "origin", rev)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
|
|
@ -342,8 +364,8 @@ func needResync(localDir, rev string) (bool, error) {
|
||||||
}
|
}
|
||||||
remote = strings.Trim(remote, "\n")
|
remote = strings.Trim(remote, "\n")
|
||||||
|
|
||||||
log.Printf("local hash: %s", local)
|
log.V(2).Infof("local hash: %s", local)
|
||||||
log.Printf("remote hash: %s", remote)
|
log.V(2).Infof("remote hash: %s", remote)
|
||||||
return (local != remote), nil
|
return (local != remote), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -360,7 +382,7 @@ func cmdForLog(command string, args ...string) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func runCommand(cwd, command string, args ...string) (string, error) {
|
func runCommand(cwd, command string, args ...string) (string, error) {
|
||||||
log.Printf("run(%q): %s", cwd, cmdForLog(command, args...))
|
log.V(5).Infof("run(%q): %s", cwd, cmdForLog(command, args...))
|
||||||
|
|
||||||
cmd := exec.Command(command, args...)
|
cmd := exec.Command(command, args...)
|
||||||
if cwd != "" {
|
if cwd != "" {
|
||||||
|
|
@ -375,7 +397,7 @@ func runCommand(cwd, command string, args ...string) (string, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func setupGitAuth(username, password, gitURL string) error {
|
func setupGitAuth(username, password, gitURL string) error {
|
||||||
log.Println("setting up the git credential cache")
|
log.V(1).Infof("setting up the git credential cache")
|
||||||
cmd := exec.Command("git", "config", "--global", "credential.helper", "cache")
|
cmd := exec.Command("git", "config", "--global", "credential.helper", "cache")
|
||||||
output, err := cmd.CombinedOutput()
|
output, err := cmd.CombinedOutput()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -399,7 +421,7 @@ func setupGitAuth(username, password, gitURL string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func setupGitSSH() error {
|
func setupGitSSH() error {
|
||||||
log.Println("setting up git SSH credentials")
|
log.V(1).Infof("setting up git SSH credentials")
|
||||||
|
|
||||||
if _, err := os.Stat("/etc/git-secret/ssh"); err != nil {
|
if _, err := os.Stat("/etc/git-secret/ssh"); err != nil {
|
||||||
return fmt.Errorf("error: could not find SSH key Secret: %v", err)
|
return fmt.Errorf("error: could not find SSH key Secret: %v", err)
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,191 @@
|
||||||
|
Apache License
|
||||||
|
Version 2.0, January 2004
|
||||||
|
http://www.apache.org/licenses/
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||||
|
|
||||||
|
1. Definitions.
|
||||||
|
|
||||||
|
"License" shall mean the terms and conditions for use, reproduction, and
|
||||||
|
distribution as defined by Sections 1 through 9 of this document.
|
||||||
|
|
||||||
|
"Licensor" shall mean the copyright owner or entity authorized by the copyright
|
||||||
|
owner that is granting the License.
|
||||||
|
|
||||||
|
"Legal Entity" shall mean the union of the acting entity and all other entities
|
||||||
|
that control, are controlled by, or are under common control with that entity.
|
||||||
|
For the purposes of this definition, "control" means (i) the power, direct or
|
||||||
|
indirect, to cause the direction or management of such entity, whether by
|
||||||
|
contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||||
|
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||||
|
|
||||||
|
"You" (or "Your") shall mean an individual or Legal Entity exercising
|
||||||
|
permissions granted by this License.
|
||||||
|
|
||||||
|
"Source" form shall mean the preferred form for making modifications, including
|
||||||
|
but not limited to software source code, documentation source, and configuration
|
||||||
|
files.
|
||||||
|
|
||||||
|
"Object" form shall mean any form resulting from mechanical transformation or
|
||||||
|
translation of a Source form, including but not limited to compiled object code,
|
||||||
|
generated documentation, and conversions to other media types.
|
||||||
|
|
||||||
|
"Work" shall mean the work of authorship, whether in Source or Object form, made
|
||||||
|
available under the License, as indicated by a copyright notice that is included
|
||||||
|
in or attached to the work (an example is provided in the Appendix below).
|
||||||
|
|
||||||
|
"Derivative Works" shall mean any work, whether in Source or Object form, that
|
||||||
|
is based on (or derived from) the Work and for which the editorial revisions,
|
||||||
|
annotations, elaborations, or other modifications represent, as a whole, an
|
||||||
|
original work of authorship. For the purposes of this License, Derivative Works
|
||||||
|
shall not include works that remain separable from, or merely link (or bind by
|
||||||
|
name) to the interfaces of, the Work and Derivative Works thereof.
|
||||||
|
|
||||||
|
"Contribution" shall mean any work of authorship, including the original version
|
||||||
|
of the Work and any modifications or additions to that Work or Derivative Works
|
||||||
|
thereof, that is intentionally submitted to Licensor for inclusion in the Work
|
||||||
|
by the copyright owner or by an individual or Legal Entity authorized to submit
|
||||||
|
on behalf of the copyright owner. For the purposes of this definition,
|
||||||
|
"submitted" means any form of electronic, verbal, or written communication sent
|
||||||
|
to the Licensor or its representatives, including but not limited to
|
||||||
|
communication on electronic mailing lists, source code control systems, and
|
||||||
|
issue tracking systems that are managed by, or on behalf of, the Licensor for
|
||||||
|
the purpose of discussing and improving the Work, but excluding communication
|
||||||
|
that is conspicuously marked or otherwise designated in writing by the copyright
|
||||||
|
owner as "Not a Contribution."
|
||||||
|
|
||||||
|
"Contributor" shall mean Licensor and any individual or Legal Entity on behalf
|
||||||
|
of whom a Contribution has been received by Licensor and subsequently
|
||||||
|
incorporated within the Work.
|
||||||
|
|
||||||
|
2. Grant of Copyright License.
|
||||||
|
|
||||||
|
Subject to the terms and conditions of this License, each Contributor hereby
|
||||||
|
grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
|
||||||
|
irrevocable copyright license to reproduce, prepare Derivative Works of,
|
||||||
|
publicly display, publicly perform, sublicense, and distribute the Work and such
|
||||||
|
Derivative Works in Source or Object form.
|
||||||
|
|
||||||
|
3. Grant of Patent License.
|
||||||
|
|
||||||
|
Subject to the terms and conditions of this License, each Contributor hereby
|
||||||
|
grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
|
||||||
|
irrevocable (except as stated in this section) patent license to make, have
|
||||||
|
made, use, offer to sell, sell, import, and otherwise transfer the Work, where
|
||||||
|
such license applies only to those patent claims licensable by such Contributor
|
||||||
|
that are necessarily infringed by their Contribution(s) alone or by combination
|
||||||
|
of their Contribution(s) with the Work to which such Contribution(s) was
|
||||||
|
submitted. If You institute patent litigation against any entity (including a
|
||||||
|
cross-claim or counterclaim in a lawsuit) alleging that the Work or a
|
||||||
|
Contribution incorporated within the Work constitutes direct or contributory
|
||||||
|
patent infringement, then any patent licenses granted to You under this License
|
||||||
|
for that Work shall terminate as of the date such litigation is filed.
|
||||||
|
|
||||||
|
4. Redistribution.
|
||||||
|
|
||||||
|
You may reproduce and distribute copies of the Work or Derivative Works thereof
|
||||||
|
in any medium, with or without modifications, and in Source or Object form,
|
||||||
|
provided that You meet the following conditions:
|
||||||
|
|
||||||
|
You must give any other recipients of the Work or Derivative Works a copy of
|
||||||
|
this License; and
|
||||||
|
You must cause any modified files to carry prominent notices stating that You
|
||||||
|
changed the files; and
|
||||||
|
You must retain, in the Source form of any Derivative Works that You distribute,
|
||||||
|
all copyright, patent, trademark, and attribution notices from the Source form
|
||||||
|
of the Work, excluding those notices that do not pertain to any part of the
|
||||||
|
Derivative Works; and
|
||||||
|
If the Work includes a "NOTICE" text file as part of its distribution, then any
|
||||||
|
Derivative Works that You distribute must include a readable copy of the
|
||||||
|
attribution notices contained within such NOTICE file, excluding those notices
|
||||||
|
that do not pertain to any part of the Derivative Works, in at least one of the
|
||||||
|
following places: within a NOTICE text file distributed as part of the
|
||||||
|
Derivative Works; within the Source form or documentation, if provided along
|
||||||
|
with the Derivative Works; or, within a display generated by the Derivative
|
||||||
|
Works, if and wherever such third-party notices normally appear. The contents of
|
||||||
|
the NOTICE file are for informational purposes only and do not modify the
|
||||||
|
License. You may add Your own attribution notices within Derivative Works that
|
||||||
|
You distribute, alongside or as an addendum to the NOTICE text from the Work,
|
||||||
|
provided that such additional attribution notices cannot be construed as
|
||||||
|
modifying the License.
|
||||||
|
You may add Your own copyright statement to Your modifications and may provide
|
||||||
|
additional or different license terms and conditions for use, reproduction, or
|
||||||
|
distribution of Your modifications, or for any such Derivative Works as a whole,
|
||||||
|
provided Your use, reproduction, and distribution of the Work otherwise complies
|
||||||
|
with the conditions stated in this License.
|
||||||
|
|
||||||
|
5. Submission of Contributions.
|
||||||
|
|
||||||
|
Unless You explicitly state otherwise, any Contribution intentionally submitted
|
||||||
|
for inclusion in the Work by You to the Licensor shall be under the terms and
|
||||||
|
conditions of this License, without any additional terms or conditions.
|
||||||
|
Notwithstanding the above, nothing herein shall supersede or modify the terms of
|
||||||
|
any separate license agreement you may have executed with Licensor regarding
|
||||||
|
such Contributions.
|
||||||
|
|
||||||
|
6. Trademarks.
|
||||||
|
|
||||||
|
This License does not grant permission to use the trade names, trademarks,
|
||||||
|
service marks, or product names of the Licensor, except as required for
|
||||||
|
reasonable and customary use in describing the origin of the Work and
|
||||||
|
reproducing the content of the NOTICE file.
|
||||||
|
|
||||||
|
7. Disclaimer of Warranty.
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, Licensor provides the
|
||||||
|
Work (and each Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
|
||||||
|
including, without limitation, any warranties or conditions of TITLE,
|
||||||
|
NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are
|
||||||
|
solely responsible for determining the appropriateness of using or
|
||||||
|
redistributing the Work and assume any risks associated with Your exercise of
|
||||||
|
permissions under this License.
|
||||||
|
|
||||||
|
8. Limitation of Liability.
|
||||||
|
|
||||||
|
In no event and under no legal theory, whether in tort (including negligence),
|
||||||
|
contract, or otherwise, unless required by applicable law (such as deliberate
|
||||||
|
and grossly negligent acts) or agreed to in writing, shall any Contributor be
|
||||||
|
liable to You for damages, including any direct, indirect, special, incidental,
|
||||||
|
or consequential damages of any character arising as a result of this License or
|
||||||
|
out of the use or inability to use the Work (including but not limited to
|
||||||
|
damages for loss of goodwill, work stoppage, computer failure or malfunction, or
|
||||||
|
any and all other commercial damages or losses), even if such Contributor has
|
||||||
|
been advised of the possibility of such damages.
|
||||||
|
|
||||||
|
9. Accepting Warranty or Additional Liability.
|
||||||
|
|
||||||
|
While redistributing the Work or Derivative Works thereof, You may choose to
|
||||||
|
offer, and charge a fee for, acceptance of support, warranty, indemnity, or
|
||||||
|
other liability obligations and/or rights consistent with this License. However,
|
||||||
|
in accepting such obligations, You may act only on Your own behalf and on Your
|
||||||
|
sole responsibility, not on behalf of any other Contributor, and only if You
|
||||||
|
agree to indemnify, defend, and hold each Contributor harmless for any liability
|
||||||
|
incurred by, or claims asserted against, such Contributor by reason of your
|
||||||
|
accepting any such warranty or additional liability.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
APPENDIX: How to apply the Apache License to your work
|
||||||
|
|
||||||
|
To apply the Apache License to your work, attach the following boilerplate
|
||||||
|
notice, with the fields enclosed by brackets "[]" replaced with your own
|
||||||
|
identifying information. (Don't include the brackets!) The text should be
|
||||||
|
enclosed in the appropriate comment syntax for the file format. We also
|
||||||
|
recommend that a file or class name and description of purpose be included on
|
||||||
|
the same "printed page" as the copyright notice for easier identification within
|
||||||
|
third-party archives.
|
||||||
|
|
||||||
|
Copyright [yyyy] [name of copyright owner]
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
@ -0,0 +1,44 @@
|
||||||
|
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 for 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 golang-nuts@googlegroups.com.
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,124 @@
|
||||||
|
// Go support for leveled logs, analogous to https://code.google.com/p/google-glog/
|
||||||
|
//
|
||||||
|
// Copyright 2013 Google Inc. All Rights Reserved.
|
||||||
|
//
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
// File I/O for logs.
|
||||||
|
|
||||||
|
package glog
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"flag"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"os/user"
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
"sync"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// MaxSize is the maximum size of a log file in bytes.
|
||||||
|
var MaxSize uint64 = 1024 * 1024 * 1800
|
||||||
|
|
||||||
|
// logDirs lists the candidate directories for new log files.
|
||||||
|
var logDirs []string
|
||||||
|
|
||||||
|
// If non-empty, overrides the choice of directory in which to write logs.
|
||||||
|
// See createLogDirs for the full list of possible destinations.
|
||||||
|
var logDir = flag.String("log_dir", "", "If non-empty, write log files in this directory")
|
||||||
|
|
||||||
|
func createLogDirs() {
|
||||||
|
if *logDir != "" {
|
||||||
|
logDirs = append(logDirs, *logDir)
|
||||||
|
}
|
||||||
|
logDirs = append(logDirs, os.TempDir())
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
pid = os.Getpid()
|
||||||
|
program = filepath.Base(os.Args[0])
|
||||||
|
host = "unknownhost"
|
||||||
|
userName = "unknownuser"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
h, err := os.Hostname()
|
||||||
|
if err == nil {
|
||||||
|
host = shortHostname(h)
|
||||||
|
}
|
||||||
|
|
||||||
|
current, err := user.Current()
|
||||||
|
if err == nil {
|
||||||
|
userName = current.Username
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sanitize userName since it may contain filepath separators on Windows.
|
||||||
|
userName = strings.Replace(userName, `\`, "_", -1)
|
||||||
|
}
|
||||||
|
|
||||||
|
// shortHostname returns its argument, truncating at the first period.
|
||||||
|
// For instance, given "www.google.com" it returns "www".
|
||||||
|
func shortHostname(hostname string) string {
|
||||||
|
if i := strings.Index(hostname, "."); i >= 0 {
|
||||||
|
return hostname[:i]
|
||||||
|
}
|
||||||
|
return hostname
|
||||||
|
}
|
||||||
|
|
||||||
|
// logName returns a new log file name containing tag, with start time t, and
|
||||||
|
// the name for the symlink for tag.
|
||||||
|
func logName(tag string, t time.Time) (name, link string) {
|
||||||
|
name = fmt.Sprintf("%s.%s.%s.log.%s.%04d%02d%02d-%02d%02d%02d.%d",
|
||||||
|
program,
|
||||||
|
host,
|
||||||
|
userName,
|
||||||
|
tag,
|
||||||
|
t.Year(),
|
||||||
|
t.Month(),
|
||||||
|
t.Day(),
|
||||||
|
t.Hour(),
|
||||||
|
t.Minute(),
|
||||||
|
t.Second(),
|
||||||
|
pid)
|
||||||
|
return name, program + "." + tag
|
||||||
|
}
|
||||||
|
|
||||||
|
var onceLogDirs sync.Once
|
||||||
|
|
||||||
|
// create creates a new log file and returns the file and its filename, which
|
||||||
|
// contains tag ("INFO", "FATAL", etc.) and t. If the file is created
|
||||||
|
// successfully, create also attempts to update the symlink for that tag, ignoring
|
||||||
|
// errors.
|
||||||
|
func create(tag string, t time.Time) (f *os.File, filename string, err error) {
|
||||||
|
onceLogDirs.Do(createLogDirs)
|
||||||
|
if len(logDirs) == 0 {
|
||||||
|
return nil, "", errors.New("log: no log dirs")
|
||||||
|
}
|
||||||
|
name, link := logName(tag, t)
|
||||||
|
var lastErr error
|
||||||
|
for _, dir := range logDirs {
|
||||||
|
fname := filepath.Join(dir, name)
|
||||||
|
f, err := os.Create(fname)
|
||||||
|
if err == nil {
|
||||||
|
symlink := filepath.Join(dir, link)
|
||||||
|
os.Remove(symlink) // ignore err
|
||||||
|
os.Symlink(name, symlink) // ignore err
|
||||||
|
return f, fname, nil
|
||||||
|
}
|
||||||
|
lastErr = err
|
||||||
|
}
|
||||||
|
return nil, "", fmt.Errorf("log: cannot create log: %v", lastErr)
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,201 @@
|
||||||
|
Apache License
|
||||||
|
Version 2.0, January 2004
|
||||||
|
http://www.apache.org/licenses/
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||||
|
|
||||||
|
1. Definitions.
|
||||||
|
|
||||||
|
"License" shall mean the terms and conditions for use, reproduction,
|
||||||
|
and distribution as defined by Sections 1 through 9 of this document.
|
||||||
|
|
||||||
|
"Licensor" shall mean the copyright owner or entity authorized by
|
||||||
|
the copyright owner that is granting the License.
|
||||||
|
|
||||||
|
"Legal Entity" shall mean the union of the acting entity and all
|
||||||
|
other entities that control, are controlled by, or are under common
|
||||||
|
control with that entity. For the purposes of this definition,
|
||||||
|
"control" means (i) the power, direct or indirect, to cause the
|
||||||
|
direction or management of such entity, whether by contract or
|
||||||
|
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||||
|
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||||
|
|
||||||
|
"You" (or "Your") shall mean an individual or Legal Entity
|
||||||
|
exercising permissions granted by this License.
|
||||||
|
|
||||||
|
"Source" form shall mean the preferred form for making modifications,
|
||||||
|
including but not limited to software source code, documentation
|
||||||
|
source, and configuration files.
|
||||||
|
|
||||||
|
"Object" form shall mean any form resulting from mechanical
|
||||||
|
transformation or translation of a Source form, including but
|
||||||
|
not limited to compiled object code, generated documentation,
|
||||||
|
and conversions to other media types.
|
||||||
|
|
||||||
|
"Work" shall mean the work of authorship, whether in Source or
|
||||||
|
Object form, made available under the License, as indicated by a
|
||||||
|
copyright notice that is included in or attached to the work
|
||||||
|
(an example is provided in the Appendix below).
|
||||||
|
|
||||||
|
"Derivative Works" shall mean any work, whether in Source or Object
|
||||||
|
form, that is based on (or derived from) the Work and for which the
|
||||||
|
editorial revisions, annotations, elaborations, or other modifications
|
||||||
|
represent, as a whole, an original work of authorship. For the purposes
|
||||||
|
of this License, Derivative Works shall not include works that remain
|
||||||
|
separable from, or merely link (or bind by name) to the interfaces of,
|
||||||
|
the Work and Derivative Works thereof.
|
||||||
|
|
||||||
|
"Contribution" shall mean any work of authorship, including
|
||||||
|
the original version of the Work and any modifications or additions
|
||||||
|
to that Work or Derivative Works thereof, that is intentionally
|
||||||
|
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||||
|
or by an individual or Legal Entity authorized to submit on behalf of
|
||||||
|
the copyright owner. For the purposes of this definition, "submitted"
|
||||||
|
means any form of electronic, verbal, or written communication sent
|
||||||
|
to the Licensor or its representatives, including but not limited to
|
||||||
|
communication on electronic mailing lists, source code control systems,
|
||||||
|
and issue tracking systems that are managed by, or on behalf of, the
|
||||||
|
Licensor for the purpose of discussing and improving the Work, but
|
||||||
|
excluding communication that is conspicuously marked or otherwise
|
||||||
|
designated in writing by the copyright owner as "Not a Contribution."
|
||||||
|
|
||||||
|
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||||
|
on behalf of whom a Contribution has been received by Licensor and
|
||||||
|
subsequently incorporated within the Work.
|
||||||
|
|
||||||
|
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
copyright license to reproduce, prepare Derivative Works of,
|
||||||
|
publicly display, publicly perform, sublicense, and distribute the
|
||||||
|
Work and such Derivative Works in Source or Object form.
|
||||||
|
|
||||||
|
3. Grant of Patent License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
(except as stated in this section) patent license to make, have made,
|
||||||
|
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||||
|
where such license applies only to those patent claims licensable
|
||||||
|
by such Contributor that are necessarily infringed by their
|
||||||
|
Contribution(s) alone or by combination of their Contribution(s)
|
||||||
|
with the Work to which such Contribution(s) was submitted. If You
|
||||||
|
institute patent litigation against any entity (including a
|
||||||
|
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||||
|
or a Contribution incorporated within the Work constitutes direct
|
||||||
|
or contributory patent infringement, then any patent licenses
|
||||||
|
granted to You under this License for that Work shall terminate
|
||||||
|
as of the date such litigation is filed.
|
||||||
|
|
||||||
|
4. Redistribution. You may reproduce and distribute copies of the
|
||||||
|
Work or Derivative Works thereof in any medium, with or without
|
||||||
|
modifications, and in Source or Object form, provided that You
|
||||||
|
meet the following conditions:
|
||||||
|
|
||||||
|
(a) You must give any other recipients of the Work or
|
||||||
|
Derivative Works a copy of this License; and
|
||||||
|
|
||||||
|
(b) You must cause any modified files to carry prominent notices
|
||||||
|
stating that You changed the files; and
|
||||||
|
|
||||||
|
(c) You must retain, in the Source form of any Derivative Works
|
||||||
|
that You distribute, all copyright, patent, trademark, and
|
||||||
|
attribution notices from the Source form of the Work,
|
||||||
|
excluding those notices that do not pertain to any part of
|
||||||
|
the Derivative Works; and
|
||||||
|
|
||||||
|
(d) If the Work includes a "NOTICE" text file as part of its
|
||||||
|
distribution, then any Derivative Works that You distribute must
|
||||||
|
include a readable copy of the attribution notices contained
|
||||||
|
within such NOTICE file, excluding those notices that do not
|
||||||
|
pertain to any part of the Derivative Works, in at least one
|
||||||
|
of the following places: within a NOTICE text file distributed
|
||||||
|
as part of the Derivative Works; within the Source form or
|
||||||
|
documentation, if provided along with the Derivative Works; or,
|
||||||
|
within a display generated by the Derivative Works, if and
|
||||||
|
wherever such third-party notices normally appear. The contents
|
||||||
|
of the NOTICE file are for informational purposes only and
|
||||||
|
do not modify the License. You may add Your own attribution
|
||||||
|
notices within Derivative Works that You distribute, alongside
|
||||||
|
or as an addendum to the NOTICE text from the Work, provided
|
||||||
|
that such additional attribution notices cannot be construed
|
||||||
|
as modifying the License.
|
||||||
|
|
||||||
|
You may add Your own copyright statement to Your modifications and
|
||||||
|
may provide additional or different license terms and conditions
|
||||||
|
for use, reproduction, or distribution of Your modifications, or
|
||||||
|
for any such Derivative Works as a whole, provided Your use,
|
||||||
|
reproduction, and distribution of the Work otherwise complies with
|
||||||
|
the conditions stated in this License.
|
||||||
|
|
||||||
|
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||||
|
any Contribution intentionally submitted for inclusion in the Work
|
||||||
|
by You to the Licensor shall be under the terms and conditions of
|
||||||
|
this License, without any additional terms or conditions.
|
||||||
|
Notwithstanding the above, nothing herein shall supersede or modify
|
||||||
|
the terms of any separate license agreement you may have executed
|
||||||
|
with Licensor regarding such Contributions.
|
||||||
|
|
||||||
|
6. Trademarks. This License does not grant permission to use the trade
|
||||||
|
names, trademarks, service marks, or product names of the Licensor,
|
||||||
|
except as required for reasonable and customary use in describing the
|
||||||
|
origin of the Work and reproducing the content of the NOTICE file.
|
||||||
|
|
||||||
|
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||||
|
agreed to in writing, Licensor provides the Work (and each
|
||||||
|
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
implied, including, without limitation, any warranties or conditions
|
||||||
|
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||||
|
appropriateness of using or redistributing the Work and assume any
|
||||||
|
risks associated with Your exercise of permissions under this License.
|
||||||
|
|
||||||
|
8. Limitation of Liability. In no event and under no legal theory,
|
||||||
|
whether in tort (including negligence), contract, or otherwise,
|
||||||
|
unless required by applicable law (such as deliberate and grossly
|
||||||
|
negligent acts) or agreed to in writing, shall any Contributor be
|
||||||
|
liable to You for damages, including any direct, indirect, special,
|
||||||
|
incidental, or consequential damages of any character arising as a
|
||||||
|
result of this License or out of the use or inability to use the
|
||||||
|
Work (including but not limited to damages for loss of goodwill,
|
||||||
|
work stoppage, computer failure or malfunction, or any and all
|
||||||
|
other commercial damages or losses), even if such Contributor
|
||||||
|
has been advised of the possibility of such damages.
|
||||||
|
|
||||||
|
9. Accepting Warranty or Additional Liability. While redistributing
|
||||||
|
the Work or Derivative Works thereof, You may choose to offer,
|
||||||
|
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||||
|
or other liability obligations and/or rights consistent with this
|
||||||
|
License. However, in accepting such obligations, You may act only
|
||||||
|
on Your own behalf and on Your sole responsibility, not on behalf
|
||||||
|
of any other Contributor, and only if You agree to indemnify,
|
||||||
|
defend, and hold each Contributor harmless for any liability
|
||||||
|
incurred by, or claims asserted against, such Contributor by reason
|
||||||
|
of your accepting any such warranty or additional liability.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
APPENDIX: How to apply the Apache License to your work.
|
||||||
|
|
||||||
|
To apply the Apache License to your work, attach the following
|
||||||
|
boilerplate notice, with the fields enclosed by brackets "{}"
|
||||||
|
replaced with your own identifying information. (Don't include
|
||||||
|
the brackets!) The text should be enclosed in the appropriate
|
||||||
|
comment syntax for the file format. We also recommend that a
|
||||||
|
file or class name and description of purpose be included on the
|
||||||
|
same "printed page" as the copyright notice for easier
|
||||||
|
identification within third-party archives.
|
||||||
|
|
||||||
|
Copyright {yyyy} {name of copyright owner}
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
# Minimal Go logging using glog
|
||||||
|
|
||||||
|
This package implements the [logr interface](https://github.com/thockin/logr)
|
||||||
|
in terms of Google's [glog](https://godoc.org/github.com/golang/glog). This
|
||||||
|
provides a relatively minimalist API to logging in Go, backed by a well-proven
|
||||||
|
implementation.
|
||||||
|
|
||||||
|
This is a BETA grade implementation.
|
||||||
|
|
@ -0,0 +1,86 @@
|
||||||
|
// Package glogr implements github.com/thockin/logr.Logger in terms of
|
||||||
|
// github.com/golang/glog.
|
||||||
|
package glogr
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"runtime"
|
||||||
|
|
||||||
|
"github.com/golang/glog"
|
||||||
|
"github.com/thockin/logr"
|
||||||
|
)
|
||||||
|
|
||||||
|
// New returns a logr.Logger which is implemented by glog.
|
||||||
|
func New() (logr.Logger, error) {
|
||||||
|
return glogger{
|
||||||
|
level: 0,
|
||||||
|
prefix: "",
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type glogger struct {
|
||||||
|
level int
|
||||||
|
prefix string
|
||||||
|
}
|
||||||
|
|
||||||
|
func prepend(prefix interface{}, args []interface{}) []interface{} {
|
||||||
|
return append([]interface{}{prefix}, args...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Magic string for intermediate frames that we should ignore.
|
||||||
|
const autogeneratedFrameName = "<autogenerated>"
|
||||||
|
|
||||||
|
// Discover how many frames we need to climb to find the caller. This approach
|
||||||
|
// was suggested by Ian Lance Taylor of the Go team, so it *should* be safe
|
||||||
|
// enough (famous last words).
|
||||||
|
func framesToCaller() int {
|
||||||
|
// 1 is the immediate caller. 3 should be too many.
|
||||||
|
for i := 1; i < 3; i++ {
|
||||||
|
_, file, _, _ := runtime.Caller(i + 1) // +1 for this function's frame
|
||||||
|
if file != autogeneratedFrameName {
|
||||||
|
return i
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 1 // something went wrong, this is safe
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l glogger) Info(args ...interface{}) {
|
||||||
|
if l.Enabled() {
|
||||||
|
glog.InfoDepth(framesToCaller(), prepend(l.prefix, args)...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l glogger) Infof(format string, args ...interface{}) {
|
||||||
|
if l.Enabled() {
|
||||||
|
glog.InfoDepth(framesToCaller(), fmt.Sprintf("%s"+format, prepend(l.prefix, args)...))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l glogger) Enabled() bool {
|
||||||
|
return bool(glog.V(glog.Level(l.level)))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l glogger) Error(args ...interface{}) {
|
||||||
|
glog.ErrorDepth(framesToCaller(), prepend(l.prefix, args)...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l glogger) Errorf(format string, args ...interface{}) {
|
||||||
|
glog.ErrorDepth(framesToCaller(), fmt.Sprintf("%s"+format, prepend(l.prefix, args)...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l glogger) V(level int) logr.InfoLogger {
|
||||||
|
return glogger{
|
||||||
|
level: level,
|
||||||
|
prefix: l.prefix,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l glogger) NewWithPrefix(prefix string) logr.Logger {
|
||||||
|
return glogger{
|
||||||
|
level: l.level,
|
||||||
|
prefix: prefix,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ logr.Logger = glogger{}
|
||||||
|
var _ logr.InfoLogger = glogger{}
|
||||||
|
|
@ -0,0 +1,201 @@
|
||||||
|
Apache License
|
||||||
|
Version 2.0, January 2004
|
||||||
|
http://www.apache.org/licenses/
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||||
|
|
||||||
|
1. Definitions.
|
||||||
|
|
||||||
|
"License" shall mean the terms and conditions for use, reproduction,
|
||||||
|
and distribution as defined by Sections 1 through 9 of this document.
|
||||||
|
|
||||||
|
"Licensor" shall mean the copyright owner or entity authorized by
|
||||||
|
the copyright owner that is granting the License.
|
||||||
|
|
||||||
|
"Legal Entity" shall mean the union of the acting entity and all
|
||||||
|
other entities that control, are controlled by, or are under common
|
||||||
|
control with that entity. For the purposes of this definition,
|
||||||
|
"control" means (i) the power, direct or indirect, to cause the
|
||||||
|
direction or management of such entity, whether by contract or
|
||||||
|
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||||
|
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||||
|
|
||||||
|
"You" (or "Your") shall mean an individual or Legal Entity
|
||||||
|
exercising permissions granted by this License.
|
||||||
|
|
||||||
|
"Source" form shall mean the preferred form for making modifications,
|
||||||
|
including but not limited to software source code, documentation
|
||||||
|
source, and configuration files.
|
||||||
|
|
||||||
|
"Object" form shall mean any form resulting from mechanical
|
||||||
|
transformation or translation of a Source form, including but
|
||||||
|
not limited to compiled object code, generated documentation,
|
||||||
|
and conversions to other media types.
|
||||||
|
|
||||||
|
"Work" shall mean the work of authorship, whether in Source or
|
||||||
|
Object form, made available under the License, as indicated by a
|
||||||
|
copyright notice that is included in or attached to the work
|
||||||
|
(an example is provided in the Appendix below).
|
||||||
|
|
||||||
|
"Derivative Works" shall mean any work, whether in Source or Object
|
||||||
|
form, that is based on (or derived from) the Work and for which the
|
||||||
|
editorial revisions, annotations, elaborations, or other modifications
|
||||||
|
represent, as a whole, an original work of authorship. For the purposes
|
||||||
|
of this License, Derivative Works shall not include works that remain
|
||||||
|
separable from, or merely link (or bind by name) to the interfaces of,
|
||||||
|
the Work and Derivative Works thereof.
|
||||||
|
|
||||||
|
"Contribution" shall mean any work of authorship, including
|
||||||
|
the original version of the Work and any modifications or additions
|
||||||
|
to that Work or Derivative Works thereof, that is intentionally
|
||||||
|
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||||
|
or by an individual or Legal Entity authorized to submit on behalf of
|
||||||
|
the copyright owner. For the purposes of this definition, "submitted"
|
||||||
|
means any form of electronic, verbal, or written communication sent
|
||||||
|
to the Licensor or its representatives, including but not limited to
|
||||||
|
communication on electronic mailing lists, source code control systems,
|
||||||
|
and issue tracking systems that are managed by, or on behalf of, the
|
||||||
|
Licensor for the purpose of discussing and improving the Work, but
|
||||||
|
excluding communication that is conspicuously marked or otherwise
|
||||||
|
designated in writing by the copyright owner as "Not a Contribution."
|
||||||
|
|
||||||
|
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||||
|
on behalf of whom a Contribution has been received by Licensor and
|
||||||
|
subsequently incorporated within the Work.
|
||||||
|
|
||||||
|
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
copyright license to reproduce, prepare Derivative Works of,
|
||||||
|
publicly display, publicly perform, sublicense, and distribute the
|
||||||
|
Work and such Derivative Works in Source or Object form.
|
||||||
|
|
||||||
|
3. Grant of Patent License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
(except as stated in this section) patent license to make, have made,
|
||||||
|
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||||
|
where such license applies only to those patent claims licensable
|
||||||
|
by such Contributor that are necessarily infringed by their
|
||||||
|
Contribution(s) alone or by combination of their Contribution(s)
|
||||||
|
with the Work to which such Contribution(s) was submitted. If You
|
||||||
|
institute patent litigation against any entity (including a
|
||||||
|
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||||
|
or a Contribution incorporated within the Work constitutes direct
|
||||||
|
or contributory patent infringement, then any patent licenses
|
||||||
|
granted to You under this License for that Work shall terminate
|
||||||
|
as of the date such litigation is filed.
|
||||||
|
|
||||||
|
4. Redistribution. You may reproduce and distribute copies of the
|
||||||
|
Work or Derivative Works thereof in any medium, with or without
|
||||||
|
modifications, and in Source or Object form, provided that You
|
||||||
|
meet the following conditions:
|
||||||
|
|
||||||
|
(a) You must give any other recipients of the Work or
|
||||||
|
Derivative Works a copy of this License; and
|
||||||
|
|
||||||
|
(b) You must cause any modified files to carry prominent notices
|
||||||
|
stating that You changed the files; and
|
||||||
|
|
||||||
|
(c) You must retain, in the Source form of any Derivative Works
|
||||||
|
that You distribute, all copyright, patent, trademark, and
|
||||||
|
attribution notices from the Source form of the Work,
|
||||||
|
excluding those notices that do not pertain to any part of
|
||||||
|
the Derivative Works; and
|
||||||
|
|
||||||
|
(d) If the Work includes a "NOTICE" text file as part of its
|
||||||
|
distribution, then any Derivative Works that You distribute must
|
||||||
|
include a readable copy of the attribution notices contained
|
||||||
|
within such NOTICE file, excluding those notices that do not
|
||||||
|
pertain to any part of the Derivative Works, in at least one
|
||||||
|
of the following places: within a NOTICE text file distributed
|
||||||
|
as part of the Derivative Works; within the Source form or
|
||||||
|
documentation, if provided along with the Derivative Works; or,
|
||||||
|
within a display generated by the Derivative Works, if and
|
||||||
|
wherever such third-party notices normally appear. The contents
|
||||||
|
of the NOTICE file are for informational purposes only and
|
||||||
|
do not modify the License. You may add Your own attribution
|
||||||
|
notices within Derivative Works that You distribute, alongside
|
||||||
|
or as an addendum to the NOTICE text from the Work, provided
|
||||||
|
that such additional attribution notices cannot be construed
|
||||||
|
as modifying the License.
|
||||||
|
|
||||||
|
You may add Your own copyright statement to Your modifications and
|
||||||
|
may provide additional or different license terms and conditions
|
||||||
|
for use, reproduction, or distribution of Your modifications, or
|
||||||
|
for any such Derivative Works as a whole, provided Your use,
|
||||||
|
reproduction, and distribution of the Work otherwise complies with
|
||||||
|
the conditions stated in this License.
|
||||||
|
|
||||||
|
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||||
|
any Contribution intentionally submitted for inclusion in the Work
|
||||||
|
by You to the Licensor shall be under the terms and conditions of
|
||||||
|
this License, without any additional terms or conditions.
|
||||||
|
Notwithstanding the above, nothing herein shall supersede or modify
|
||||||
|
the terms of any separate license agreement you may have executed
|
||||||
|
with Licensor regarding such Contributions.
|
||||||
|
|
||||||
|
6. Trademarks. This License does not grant permission to use the trade
|
||||||
|
names, trademarks, service marks, or product names of the Licensor,
|
||||||
|
except as required for reasonable and customary use in describing the
|
||||||
|
origin of the Work and reproducing the content of the NOTICE file.
|
||||||
|
|
||||||
|
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||||
|
agreed to in writing, Licensor provides the Work (and each
|
||||||
|
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
implied, including, without limitation, any warranties or conditions
|
||||||
|
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||||
|
appropriateness of using or redistributing the Work and assume any
|
||||||
|
risks associated with Your exercise of permissions under this License.
|
||||||
|
|
||||||
|
8. Limitation of Liability. In no event and under no legal theory,
|
||||||
|
whether in tort (including negligence), contract, or otherwise,
|
||||||
|
unless required by applicable law (such as deliberate and grossly
|
||||||
|
negligent acts) or agreed to in writing, shall any Contributor be
|
||||||
|
liable to You for damages, including any direct, indirect, special,
|
||||||
|
incidental, or consequential damages of any character arising as a
|
||||||
|
result of this License or out of the use or inability to use the
|
||||||
|
Work (including but not limited to damages for loss of goodwill,
|
||||||
|
work stoppage, computer failure or malfunction, or any and all
|
||||||
|
other commercial damages or losses), even if such Contributor
|
||||||
|
has been advised of the possibility of such damages.
|
||||||
|
|
||||||
|
9. Accepting Warranty or Additional Liability. While redistributing
|
||||||
|
the Work or Derivative Works thereof, You may choose to offer,
|
||||||
|
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||||
|
or other liability obligations and/or rights consistent with this
|
||||||
|
License. However, in accepting such obligations, You may act only
|
||||||
|
on Your own behalf and on Your sole responsibility, not on behalf
|
||||||
|
of any other Contributor, and only if You agree to indemnify,
|
||||||
|
defend, and hold each Contributor harmless for any liability
|
||||||
|
incurred by, or claims asserted against, such Contributor by reason
|
||||||
|
of your accepting any such warranty or additional liability.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
APPENDIX: How to apply the Apache License to your work.
|
||||||
|
|
||||||
|
To apply the Apache License to your work, attach the following
|
||||||
|
boilerplate notice, with the fields enclosed by brackets "{}"
|
||||||
|
replaced with your own identifying information. (Don't include
|
||||||
|
the brackets!) The text should be enclosed in the appropriate
|
||||||
|
comment syntax for the file format. We also recommend that a
|
||||||
|
file or class name and description of purpose be included on the
|
||||||
|
same "printed page" as the copyright notice for easier
|
||||||
|
identification within third-party archives.
|
||||||
|
|
||||||
|
Copyright {yyyy} {name of copyright owner}
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
@ -0,0 +1,36 @@
|
||||||
|
# A more minimal logging API for Go
|
||||||
|
|
||||||
|
Before you consider this package, please read [this blog post by the inimitable
|
||||||
|
Dave Cheney](http://dave.cheney.net/2015/11/05/lets-talk-about-logging). I
|
||||||
|
really appreciate what he has to say, and it largely aligns with my own
|
||||||
|
experiences. Too many choices of levels means inconsistent logs.
|
||||||
|
|
||||||
|
This package offers a purely abstract interface, based on these ideas but with
|
||||||
|
a few twists. Code can depend on just this interface and have the actual
|
||||||
|
logging implementation be injected from callers. Ideally only `main()` knows
|
||||||
|
what logging implementation is being used.
|
||||||
|
|
||||||
|
# Differences from Dave's ideas
|
||||||
|
|
||||||
|
The main differences are:
|
||||||
|
|
||||||
|
1) Dave basically proposes doing away with the notion of a logging API in favor
|
||||||
|
of `fmt.Printf()`. I disagree, especially when you consider things like output
|
||||||
|
locations, timestamps, file and line decorations, and structured logging. I
|
||||||
|
restrict the API to just 2 types of logs: info and error.
|
||||||
|
|
||||||
|
Info logs are things you want to tell the user which are not errors. Error
|
||||||
|
logs are, well, errors. If your code receives an `error` from a subordinate
|
||||||
|
function call and is logging that `error` *and not returning it*, use error
|
||||||
|
logs.
|
||||||
|
|
||||||
|
2) Verbosity-levels on info logs. This gives developers a chance to indicate
|
||||||
|
arbitrary grades of importance for info logs, without assigning names with
|
||||||
|
semantic meaning such as "warning", "trace", and "debug". Superficially this
|
||||||
|
may feel very similar, but the primary difference is the lack of semantics.
|
||||||
|
Because verbosity is a numerical value, it's safe to assume that an app running
|
||||||
|
with higher verbosity means more (and less important) logs will be generated.
|
||||||
|
|
||||||
|
This is a BETA grade API. I have implemented it for
|
||||||
|
[glog](https://godoc.org/github.com/golang/glog). Until there is a significant
|
||||||
|
2nd implementation, I don't really know how it will change.
|
||||||
|
|
@ -0,0 +1,48 @@
|
||||||
|
// Package logr defines abstract interfaces for logging. Packages can depend on
|
||||||
|
// these interfaces and callers can implement logging in whatever way is
|
||||||
|
// appropriate.
|
||||||
|
//
|
||||||
|
// This design derives from Dave Cheney's blog:
|
||||||
|
// http://dave.cheney.net/2015/11/05/lets-talk-about-logging
|
||||||
|
//
|
||||||
|
// This is a BETA grade API. Until there is a significant 2nd implementation,
|
||||||
|
// I don't really know how it will change.
|
||||||
|
package logr
|
||||||
|
|
||||||
|
// TODO: consider structured logging, a la uber-go/zap
|
||||||
|
// TODO: consider other bits of glog functionality like Flush, InfoDepth, OutputStats
|
||||||
|
|
||||||
|
// InfoLogger represents the ability to log non-error messages.
|
||||||
|
type InfoLogger interface {
|
||||||
|
// Info logs a non-error message. This is behaviorally akin to fmt.Print.
|
||||||
|
Info(args ...interface{})
|
||||||
|
|
||||||
|
// Infof logs a formatted non-error message.
|
||||||
|
Infof(format string, args ...interface{})
|
||||||
|
|
||||||
|
// Enabled test whether this InfoLogger is enabled. For example,
|
||||||
|
// commandline flags might be used to set the logging verbosity and disable
|
||||||
|
// some info logs.
|
||||||
|
Enabled() bool
|
||||||
|
}
|
||||||
|
|
||||||
|
// Logger represents the ability to log messages, both errors and not.
|
||||||
|
type Logger interface {
|
||||||
|
// All Loggers implement InfoLogger. Calling InfoLogger methods directly on
|
||||||
|
// a Logger value is equivalent to calling them on a V(0) InfoLogger. For
|
||||||
|
// example, logger.Info() produces the same result as logger.V(0).Info.
|
||||||
|
InfoLogger
|
||||||
|
|
||||||
|
// Error logs a error message. This is behaviorally akin to fmt.Print.
|
||||||
|
Error(args ...interface{})
|
||||||
|
|
||||||
|
// Errorf logs a formatted error message.
|
||||||
|
Errorf(format string, args ...interface{})
|
||||||
|
|
||||||
|
// V returns an InfoLogger value for a specific verbosity level. A higher
|
||||||
|
// verbosity level means a log message is less important.
|
||||||
|
V(level int) InfoLogger
|
||||||
|
|
||||||
|
// NewWithPrefix returns a Logger which prefixes all messages.
|
||||||
|
NewWithPrefix(prefix string) Logger
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue