diff --git a/Godeps/Godeps.json b/Godeps/Godeps.json index f92a81af7..a06204965 100644 --- a/Godeps/Godeps.json +++ b/Godeps/Godeps.json @@ -231,10 +231,6 @@ "ImportPath": "github.com/syndtr/gosnappy/snappy", "Rev": "156a073208e131d7d2e212cb749feae7c339e846" }, - { - "ImportPath": "github.com/whyrusleeping/go-logging", - "Rev": "128b9855511a4ea3ccbcf712695baf2bab72e134" - }, { "ImportPath": "github.com/whyrusleeping/go-metrics", "Rev": "1cd8009604ec2238b5a71305a0ecd974066e0e16" diff --git a/Godeps/_workspace/src/github.com/whyrusleeping/go-logging/.travis.yml b/Godeps/_workspace/src/github.com/whyrusleeping/go-logging/.travis.yml deleted file mode 100644 index 70e012b81..000000000 --- a/Godeps/_workspace/src/github.com/whyrusleeping/go-logging/.travis.yml +++ /dev/null @@ -1,6 +0,0 @@ -language: go - -go: - - 1.0 - - 1.1 - - tip diff --git a/Godeps/_workspace/src/github.com/whyrusleeping/go-logging/CONTRIBUTORS b/Godeps/_workspace/src/github.com/whyrusleeping/go-logging/CONTRIBUTORS deleted file mode 100644 index 958416ef1..000000000 --- a/Godeps/_workspace/src/github.com/whyrusleeping/go-logging/CONTRIBUTORS +++ /dev/null @@ -1,5 +0,0 @@ -Alec Thomas <alec@swapoff.org> -Guilhem Lettron <guilhem.lettron@optiflows.com> -Ivan Daniluk <ivan.daniluk@gmail.com> -Nimi Wariboko Jr <nimi@channelmeter.com> -Róbert Selvek <robert.selvek@gmail.com> diff --git a/Godeps/_workspace/src/github.com/whyrusleeping/go-logging/LICENSE b/Godeps/_workspace/src/github.com/whyrusleeping/go-logging/LICENSE deleted file mode 100644 index f1f6cfcef..000000000 --- a/Godeps/_workspace/src/github.com/whyrusleeping/go-logging/LICENSE +++ /dev/null @@ -1,27 +0,0 @@ -Copyright (c) 2013 Örjan Persson. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google Inc. nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/Godeps/_workspace/src/github.com/whyrusleeping/go-logging/README.md b/Godeps/_workspace/src/github.com/whyrusleeping/go-logging/README.md deleted file mode 100644 index 566955085..000000000 --- a/Godeps/_workspace/src/github.com/whyrusleeping/go-logging/README.md +++ /dev/null @@ -1,89 +0,0 @@ -## Golang logging library - -[](https://godoc.org/github.com/op/go-logging) [](https://travis-ci.org/op/go-logging) - -Package logging implements a logging infrastructure for Go. Its output format -is customizable and supports different logging backends like syslog, file and -memory. Multiple backends can be utilized with different log levels per backend -and logger. - -## Example - -Let's have a look at an [example](examples/example.go) which demonstrates most -of the features found in this library. - -[](examples/example.go) - -```go -package main - -import ( - "os" - - "github.com/op/go-logging" -) - -var log = logging.MustGetLogger("example") - -// Example format string. Everything except the message has a custom color -// which is dependent on the log level. Many fields have a custom output -// formatting too, eg. the time returns the hour down to the milli second. -var format = logging.MustStringFormatter( - "%{color}%{time:15:04:05.000} %{shortfunc} ▶ %{level:.4s} %{id:03x}%{color:reset} %{message}", -) - -// Password is just an example type implementing the Redactor interface. Any -// time this is logged, the Redacted() function will be called. -type Password string - -func (p Password) Redacted() interface{} { - return logging.Redact(string(p)) -} - -func main() { - // For demo purposes, create two backend for os.Stderr. - backend1 := logging.NewLogBackend(os.Stderr, "", 0) - backend2 := logging.NewLogBackend(os.Stderr, "", 0) - - // For messages written to backend2 we want to add some additional - // information to the output, including the used log level and the name of - // the function. - backend2Formatter := logging.NewBackendFormatter(backend2, format) - - // Only errors and more severe messages should be sent to backend1 - backend1Leveled := logging.AddModuleLevel(backend1) - backend1Leveled.SetLevel(logging.ERROR, "") - - // Set the backends to be used. - logging.SetBackend(backend1Leveled, backend2Formatter) - - log.Debug("debug %s", Password("secret")) - log.Info("info") - log.Notice("notice") - log.Warning("warning") - log.Error("err") - log.Critical("crit") -} -``` - -## Installing - -### Using *go get* - - $ go get github.com/op/go-logging - -After this command *go-logging* is ready to use. Its source will be in: - - $GOROOT/src/pkg/github.com/op/go-logging - -You can use `go get -u` to update the package. - -## Documentation - -For docs, see http://godoc.org/github.com/op/go-logging or run: - - $ godoc github.com/op/go-logging - -## Additional resources - -* [wslog](https://godoc.org/github.com/cryptix/go/logging/wslog) -- exposes log messages through a WebSocket. diff --git a/Godeps/_workspace/src/github.com/whyrusleeping/go-logging/backend.go b/Godeps/_workspace/src/github.com/whyrusleeping/go-logging/backend.go deleted file mode 100644 index 6cd589cab..000000000 --- a/Godeps/_workspace/src/github.com/whyrusleeping/go-logging/backend.go +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright 2013, Örjan Persson. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package logging - -// defaultBackend is the backend used for all logging calls. -var defaultBackend LeveledBackend - -// Backend is the interface which a log backend need to implement to be able to -// be used as a logging backend. -type Backend interface { - Log(Level, int, *Record) error -} - -// Set backend replaces the backend currently set with the given new logging -// backend. -func SetBackend(backends ...Backend) LeveledBackend { - var backend Backend - if len(backends) == 1 { - backend = backends[0] - } else { - backend = MultiLogger(backends...) - } - - defaultBackend = AddModuleLevel(backend) - return defaultBackend -} - -// SetLevel sets the logging level for the specified module. The module -// corresponds to the string specified in GetLogger. -func SetLevel(level Level, module string) { - defaultBackend.SetLevel(level, module) -} - -// GetLevel returns the logging level for the specified module. -func GetLevel(module string) Level { - return defaultBackend.GetLevel(module) -} diff --git a/Godeps/_workspace/src/github.com/whyrusleeping/go-logging/example_test.go b/Godeps/_workspace/src/github.com/whyrusleeping/go-logging/example_test.go deleted file mode 100644 index deb8900e7..000000000 --- a/Godeps/_workspace/src/github.com/whyrusleeping/go-logging/example_test.go +++ /dev/null @@ -1,40 +0,0 @@ -package logging - -import "os" - -func Example() { - // This call is for testing purposes and will set the time to unix epoch. - InitForTesting(DEBUG) - - var log = MustGetLogger("example") - - // For demo purposes, create two backend for os.Stdout. - // - // os.Stderr should most likely be used in the real world but then the - // "Output:" check in this example would not work. - backend1 := NewLogBackend(os.Stdout, "", 0) - backend2 := NewLogBackend(os.Stdout, "", 0) - - // For messages written to backend2 we want to add some additional - // information to the output, including the used log level and the name of - // the function. - var format = MustStringFormatter( - "%{time:15:04:05.000} %{shortfunc} %{level:.1s} %{message}", - ) - backend2Formatter := NewBackendFormatter(backend2, format) - - // Only errors and more severe messages should be sent to backend2 - backend2Leveled := AddModuleLevel(backend2Formatter) - backend2Leveled.SetLevel(ERROR, "") - - // Set the backends to be used and the default level. - SetBackend(backend1, backend2Leveled) - - log.Debug("debug %s", "arg") - log.Error("error") - - // Output: - // debug arg - // error - // 00:00:00.000 Example E error -} diff --git a/Godeps/_workspace/src/github.com/whyrusleeping/go-logging/examples/example.go b/Godeps/_workspace/src/github.com/whyrusleeping/go-logging/examples/example.go deleted file mode 100644 index 163f6475b..000000000 --- a/Godeps/_workspace/src/github.com/whyrusleeping/go-logging/examples/example.go +++ /dev/null @@ -1,49 +0,0 @@ -package main - -import ( - "os" - - "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/whyrusleeping/go-logging" -) - -var log = logging.MustGetLogger("example") - -// Example format string. Everything except the message has a custom color -// which is dependent on the log level. Many fields have a custom output -// formatting too, eg. the time returns the hour down to the milli second. -var format = logging.MustStringFormatter( - "%{color}%{time:15:04:05.000} %{shortfunc} ▶ %{level:.4s} %{id:03x}%{color:reset} %{message}", -) - -// Password is just an example type implementing the Redactor interface. Any -// time this is logged, the Redacted() function will be called. -type Password string - -func (p Password) Redacted() interface{} { - return logging.Redact(string(p)) -} - -func main() { - // For demo purposes, create two backend for os.Stderr. - backend1 := logging.NewLogBackend(os.Stderr, "", 0) - backend2 := logging.NewLogBackend(os.Stderr, "", 0) - - // For messages written to backend2 we want to add some additional - // information to the output, including the used log level and the name of - // the function. - backend2Formatter := logging.NewBackendFormatter(backend2, format) - - // Only errors and more severe messages should be sent to backend1 - backend1Leveled := logging.AddModuleLevel(backend1) - backend1Leveled.SetLevel(logging.ERROR, "") - - // Set the backends to be used. - logging.SetBackend(backend1Leveled, backend2Formatter) - - log.Debug("debug %s", Password("secret")) - log.Info("info") - log.Notice("notice") - log.Warning("warning") - log.Error("err") - log.Critical("crit") -} diff --git a/Godeps/_workspace/src/github.com/whyrusleeping/go-logging/examples/example.png b/Godeps/_workspace/src/github.com/whyrusleeping/go-logging/examples/example.png deleted file mode 100644 index ff3392b7a..000000000 Binary files a/Godeps/_workspace/src/github.com/whyrusleeping/go-logging/examples/example.png and /dev/null differ diff --git a/Godeps/_workspace/src/github.com/whyrusleeping/go-logging/format.go b/Godeps/_workspace/src/github.com/whyrusleeping/go-logging/format.go deleted file mode 100644 index 99b1ddb72..000000000 --- a/Godeps/_workspace/src/github.com/whyrusleeping/go-logging/format.go +++ /dev/null @@ -1,368 +0,0 @@ -// Copyright 2013, Örjan Persson. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package logging - -import ( - "bytes" - "errors" - "fmt" - "io" - "os" - "path" - "path/filepath" - "regexp" - "runtime" - "strings" - "sync" - "time" -) - -// TODO see Formatter interface in fmt/print.go -// TODO try text/template, maybe it have enough performance -// TODO other template systems? -// TODO make it possible to specify formats per backend? -type fmtVerb int - -const ( - fmtVerbTime fmtVerb = iota - fmtVerbLevel - fmtVerbId - fmtVerbPid - fmtVerbProgram - fmtVerbModule - fmtVerbMessage - fmtVerbLongfile - fmtVerbShortfile - fmtVerbLongpkg - fmtVerbShortpkg - fmtVerbLongfunc - fmtVerbShortfunc - fmtVerbLevelColor - - // Keep last, there are no match for these below. - fmtVerbUnknown - fmtVerbStatic -) - -var fmtVerbs = []string{ - "time", - "level", - "id", - "pid", - "program", - "module", - "message", - "longfile", - "shortfile", - "longpkg", - "shortpkg", - "longfunc", - "shortfunc", - "color", -} - -const rfc3339Milli = "2006-01-02T15:04:05.999Z07:00" - -var defaultVerbsLayout = []string{ - rfc3339Milli, - "s", - "d", - "d", - "s", - "s", - "s", - "s", - "s", - "s", - "s", - "s", - "s", - "", -} - -var ( - pid = os.Getpid() - program = filepath.Base(os.Args[0]) -) - -func getFmtVerbByName(name string) fmtVerb { - for i, verb := range fmtVerbs { - if name == verb { - return fmtVerb(i) - } - } - return fmtVerbUnknown -} - -// Formatter is the required interface for a custom log record formatter. -type Formatter interface { - Format(calldepth int, r *Record, w io.Writer) error -} - -// formatter is used by all backends unless otherwise overriden. -var formatter struct { - sync.RWMutex - def Formatter -} - -func getFormatter() Formatter { - formatter.RLock() - defer formatter.RUnlock() - return formatter.def -} - -var ( - // DefaultFormatter is the default formatter used and is only the message. - DefaultFormatter Formatter = MustStringFormatter("%{message}") - - // Glog format - GlogFormatter Formatter = MustStringFormatter("%{level:.1s}%{time:0102 15:04:05.999999} %{pid} %{shortfile}] %{message}") -) - -// SetFormatter sets the default formatter for all new backends. A backend will -// fetch this value once it is needed to format a record. Note that backends -// will cache the formatter after the first point. For now, make sure to set -// the formatter before logging. -func SetFormatter(f Formatter) { - formatter.Lock() - defer formatter.Unlock() - formatter.def = f -} - -var formatRe *regexp.Regexp = regexp.MustCompile(`%{([a-z]+)(?::(.*?[^\\]))?}`) - -type part struct { - verb fmtVerb - layout string -} - -// stringFormatter contains a list of parts which explains how to build the -// formatted string passed on to the logging backend. -type stringFormatter struct { - parts []part -} - -// NewStringFormatter returns a new Formatter which outputs the log record as a -// string based on the 'verbs' specified in the format string. -// -// The verbs: -// -// General: -// %{id} Sequence number for log message (uint64). -// %{pid} Process id (int) -// %{time} Time when log occurred (time.Time) -// %{level} Log level (Level) -// %{module} Module (string) -// %{program} Basename of os.Args[0] (string) -// %{message} Message (string) -// %{longfile} Full file name and line number: /a/b/c/d.go:23 -// %{shortfile} Final file name element and line number: d.go:23 -// %{color} ANSI color based on log level -// -// For normal types, the output can be customized by using the 'verbs' defined -// in the fmt package, eg. '%{id:04d}' to make the id output be '%04d' as the -// format string. -// -// For time.Time, use the same layout as time.Format to change the time format -// when output, eg "2006-01-02T15:04:05.999Z-07:00". -// -// For the 'color' verb, the output can be adjusted to either use bold colors, -// i.e., '%{color:bold}' or to reset the ANSI attributes, i.e., -// '%{color:reset}' Note that if you use the color verb explicitly, be sure to -// reset it or else the color state will persist past your log message. e.g., -// "%{color:bold}%{time:15:04:05} %{level:-8s}%{color:reset} %{message}" will -// just colorize the time and level, leaving the message uncolored. -// -// There's also a couple of experimental 'verbs'. These are exposed to get -// feedback and needs a bit of tinkering. Hence, they might change in the -// future. -// -// Experimental: -// %{longpkg} Full package path, eg. github.com/go-logging -// %{shortpkg} Base package path, eg. go-logging -// %{longfunc} Full function name, eg. littleEndian.PutUint32 -// %{shortfunc} Base function name, eg. PutUint32 -func NewStringFormatter(format string) (*stringFormatter, error) { - var fmter = &stringFormatter{} - - // Find the boundaries of all %{vars} - matches := formatRe.FindAllStringSubmatchIndex(format, -1) - if matches == nil { - return nil, errors.New("logger: invalid log format: " + format) - } - - // Collect all variables and static text for the format - prev := 0 - for _, m := range matches { - start, end := m[0], m[1] - if start > prev { - fmter.add(fmtVerbStatic, format[prev:start]) - } - - name := format[m[2]:m[3]] - verb := getFmtVerbByName(name) - if verb == fmtVerbUnknown { - return nil, errors.New("logger: unknown variable: " + name) - } - - // Handle layout customizations or use the default. If this is not for the - // time or color formatting, we need to prefix with %. - layout := defaultVerbsLayout[verb] - if m[4] != -1 { - layout = format[m[4]:m[5]] - } - if verb != fmtVerbTime && verb != fmtVerbLevelColor { - layout = "%" + layout - } - - fmter.add(verb, layout) - prev = end - } - end := format[prev:] - if end != "" { - fmter.add(fmtVerbStatic, end) - } - - // Make a test run to make sure we can format it correctly. - t, err := time.Parse(time.RFC3339, "2010-02-04T21:00:57-08:00") - if err != nil { - panic(err) - } - r := &Record{ - Id: 12345, - Time: t, - Module: "logger", - fmt: "hello %s", - args: []interface{}{"go"}, - } - if err := fmter.Format(0, r, &bytes.Buffer{}); err != nil { - return nil, err - } - - return fmter, nil -} - -// MustStringFormatter is equivalent to NewStringFormatter with a call to panic -// on error. -func MustStringFormatter(format string) *stringFormatter { - f, err := NewStringFormatter(format) - if err != nil { - panic("Failed to initialized string formatter: " + err.Error()) - } - return f -} - -func (f *stringFormatter) add(verb fmtVerb, layout string) { - f.parts = append(f.parts, part{verb, layout}) -} - -func (f *stringFormatter) Format(calldepth int, r *Record, output io.Writer) error { - for _, part := range f.parts { - if part.verb == fmtVerbStatic { - output.Write([]byte(part.layout)) - } else if part.verb == fmtVerbTime { - output.Write([]byte(r.Time.Format(part.layout))) - } else if part.verb == fmtVerbLevelColor { - if part.layout == "bold" { - output.Write([]byte(boldcolors[r.Level])) - } else if part.layout == "reset" { - output.Write([]byte("\033[0m")) - } else { - output.Write([]byte(colors[r.Level])) - } - } else { - var v interface{} - switch part.verb { - case fmtVerbLevel: - v = r.Level - break - case fmtVerbId: - v = r.Id - break - case fmtVerbPid: - v = pid - break - case fmtVerbProgram: - v = program - break - case fmtVerbModule: - v = r.Module - break - case fmtVerbMessage: - v = r.Message() - break - case fmtVerbLongfile, fmtVerbShortfile: - _, file, line, ok := runtime.Caller(calldepth + 1) - if !ok { - file = "???" - line = 0 - } else if part.verb == fmtVerbShortfile { - file = filepath.Base(file) - } - v = fmt.Sprintf("%s:%d", file, line) - case fmtVerbLongfunc, fmtVerbShortfunc, - fmtVerbLongpkg, fmtVerbShortpkg: - // TODO cache pc - v = "???" - if pc, _, _, ok := runtime.Caller(calldepth + 1); ok { - if f := runtime.FuncForPC(pc); f != nil { - v = formatFuncName(part.verb, f.Name()) - } - } - default: - panic("unhandled format part") - } - fmt.Fprintf(output, part.layout, v) - } - } - return nil -} - -// formatFuncName tries to extract certain part of the runtime formatted -// function name to some pre-defined variation. -// -// This function is known to not work properly if the package path or name -// contains a dot. -func formatFuncName(v fmtVerb, f string) string { - i := strings.LastIndex(f, "/") - j := strings.Index(f[i+1:], ".") - if j < 1 { - return "???" - } - pkg, fun := f[:i+j+1], f[i+j+2:] - switch v { - case fmtVerbLongpkg: - return pkg - case fmtVerbShortpkg: - return path.Base(pkg) - case fmtVerbLongfunc: - return fun - case fmtVerbShortfunc: - i = strings.LastIndex(fun, ".") - return fun[i+1:] - } - panic("unexpected func formatter") -} - -// backendFormatter combines a backend with a specific formatter making it -// possible to have different log formats for different backends. -type backendFormatter struct { - b Backend - f Formatter -} - -// NewBackendFormatter creates a new backend which makes all records that -// passes through it beeing formatted by the specific formatter. -func NewBackendFormatter(b Backend, f Formatter) *backendFormatter { - return &backendFormatter{b, f} -} - -// Log implements the Log function required by the Backend interface. -func (bf *backendFormatter) Log(level Level, calldepth int, r *Record) error { - // Make a shallow copy of the record and replace any formatter - r2 := *r - r2.formatter = bf.f - return bf.b.Log(level, calldepth+1, &r2) -} diff --git a/Godeps/_workspace/src/github.com/whyrusleeping/go-logging/format_test.go b/Godeps/_workspace/src/github.com/whyrusleeping/go-logging/format_test.go deleted file mode 100644 index c008e9e8b..000000000 --- a/Godeps/_workspace/src/github.com/whyrusleeping/go-logging/format_test.go +++ /dev/null @@ -1,184 +0,0 @@ -// Copyright 2013, Örjan Persson. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package logging - -import ( - "bytes" - "testing" -) - -func TestFormat(t *testing.T) { - backend := InitForTesting(DEBUG) - - f, err := NewStringFormatter("%{shortfile} %{time:2006-01-02T15:04:05} %{level:.1s} %{id:04d} %{module} %{message}") - if err != nil { - t.Fatalf("failed to set format: %s", err) - } - SetFormatter(f) - - log := MustGetLogger("module") - log.Debug("hello") - - line := MemoryRecordN(backend, 0).Formatted(0) - if "format_test.go:24 1970-01-01T00:00:00 D 0001 module hello" != line { - t.Errorf("Unexpected format: %s", line) - } -} - -func logAndGetLine(backend *MemoryBackend) string { - MustGetLogger("foo").Debug("hello") - return MemoryRecordN(backend, 0).Formatted(1) -} - -func getLastLine(backend *MemoryBackend) string { - return MemoryRecordN(backend, 0).Formatted(1) -} - -func realFunc(backend *MemoryBackend) string { - return logAndGetLine(backend) -} - -type structFunc struct{} - -func (structFunc) Log(backend *MemoryBackend) string { - return logAndGetLine(backend) -} - -func TestRealFuncFormat(t *testing.T) { - backend := InitForTesting(DEBUG) - SetFormatter(MustStringFormatter("%{shortfunc}")) - - line := realFunc(backend) - if "realFunc" != line { - t.Errorf("Unexpected format: %s", line) - } -} - -func TestStructFuncFormat(t *testing.T) { - backend := InitForTesting(DEBUG) - SetFormatter(MustStringFormatter("%{longfunc}")) - - var x structFunc - line := x.Log(backend) - if "structFunc.Log" != line { - t.Errorf("Unexpected format: %s", line) - } -} - -func TestVarFuncFormat(t *testing.T) { - backend := InitForTesting(DEBUG) - SetFormatter(MustStringFormatter("%{shortfunc}")) - - var varFunc = func() string { - return logAndGetLine(backend) - } - - line := varFunc() - if "???" == line || "TestVarFuncFormat" == line || "varFunc" == line { - t.Errorf("Unexpected format: %s", line) - } -} - -func TestFormatFuncName(t *testing.T) { - var tests = []struct { - filename string - longpkg string - shortpkg string - longfunc string - shortfunc string - }{ - {"", - "???", - "???", - "???", - "???"}, - {"main", - "???", - "???", - "???", - "???"}, - {"main.", - "main", - "main", - "", - ""}, - {"main.main", - "main", - "main", - "main", - "main"}, - {"github.com/op/go-logging.func·001", - "github.com/op/go-logging", - "go-logging", - "func·001", - "func·001"}, - {"github.com/op/go-logging.stringFormatter.Format", - "github.com/op/go-logging", - "go-logging", - "stringFormatter.Format", - "Format"}, - } - - var v string - for _, test := range tests { - v = formatFuncName(fmtVerbLongpkg, test.filename) - if test.longpkg != v { - t.Errorf("%s != %s", test.longpkg, v) - } - v = formatFuncName(fmtVerbShortpkg, test.filename) - if test.shortpkg != v { - t.Errorf("%s != %s", test.shortpkg, v) - } - v = formatFuncName(fmtVerbLongfunc, test.filename) - if test.longfunc != v { - t.Errorf("%s != %s", test.longfunc, v) - } - v = formatFuncName(fmtVerbShortfunc, test.filename) - if test.shortfunc != v { - t.Errorf("%s != %s", test.shortfunc, v) - } - } -} - -func TestBackendFormatter(t *testing.T) { - InitForTesting(DEBUG) - - // Create two backends and wrap one of the with a backend formatter - b1 := NewMemoryBackend(1) - b2 := NewMemoryBackend(1) - - f := MustStringFormatter("%{level} %{message}") - bf := NewBackendFormatter(b2, f) - - SetBackend(b1, bf) - - log := MustGetLogger("module") - log.Info("foo") - if "foo" != getLastLine(b1) { - t.Errorf("Unexpected line: %s", getLastLine(b1)) - } - if "INFO foo" != getLastLine(b2) { - t.Errorf("Unexpected line: %s", getLastLine(b2)) - } -} - -func BenchmarkStringFormatter(b *testing.B) { - fmt := "%{time:2006-01-02T15:04:05} %{level:.1s} %{id:04d} %{module} %{message}" - f := MustStringFormatter(fmt) - - backend := InitForTesting(DEBUG) - buf := &bytes.Buffer{} - log := MustGetLogger("module") - log.Debug("") - record := MemoryRecordN(backend, 0) - - b.ResetTimer() - for i := 0; i < b.N; i++ { - if err := f.Format(1, record, buf); err != nil { - b.Fatal(err) - buf.Truncate(0) - } - } -} diff --git a/Godeps/_workspace/src/github.com/whyrusleeping/go-logging/level.go b/Godeps/_workspace/src/github.com/whyrusleeping/go-logging/level.go deleted file mode 100644 index 1ef03917e..000000000 --- a/Godeps/_workspace/src/github.com/whyrusleeping/go-logging/level.go +++ /dev/null @@ -1,124 +0,0 @@ -// Copyright 2013, Örjan Persson. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package logging - -import ( - "errors" - "strings" - "sync" -) - -var ErrInvalidLogLevel = errors.New("logger: invalid log level") - -// Level defines all available log levels for log messages. -type Level int - -const ( - CRITICAL Level = iota - ERROR - WARNING - NOTICE - INFO - DEBUG -) - -var levelNames = []string{ - "CRITICAL", - "ERROR", - "WARNING", - "NOTICE", - "INFO", - "DEBUG", -} - -// String returns the string representation of a logging level. -func (p Level) String() string { - return levelNames[p] -} - -// LogLevel returns the log level from a string representation. -func LogLevel(level string) (Level, error) { - for i, name := range levelNames { - if strings.EqualFold(name, level) { - return Level(i), nil - } - } - return ERROR, ErrInvalidLogLevel -} - -type Leveled interface { - GetLevel(string) Level - SetLevel(Level, string) - IsEnabledFor(Level, string) bool -} - -// LeveledBackend is a log backend with additional knobs for setting levels on -// individual modules to different levels. -type LeveledBackend interface { - Backend - Leveled -} - -type moduleLeveled struct { - levels map[string]Level - backend Backend - formatter Formatter - once sync.Once -} - -// AddModuleLevel wraps a log backend with knobs to have different log levels -// for different modules. -func AddModuleLevel(backend Backend) LeveledBackend { - var leveled LeveledBackend - var ok bool - if leveled, ok = backend.(LeveledBackend); !ok { - leveled = &moduleLeveled{ - levels: make(map[string]Level), - backend: backend, - } - } - return leveled -} - -// GetLevel returns the log level for the given module. -func (l *moduleLeveled) GetLevel(module string) Level { - level, exists := l.levels[module] - if exists == false { - level, exists = l.levels[""] - // no configuration exists, default to debug - if exists == false { - level = DEBUG - } - } - return level -} - -// SetLevel sets the log level for the given module. -func (l *moduleLeveled) SetLevel(level Level, module string) { - l.levels[module] = level -} - -// IsEnabledFor will return true if logging is enabled for the given module. -func (l *moduleLeveled) IsEnabledFor(level Level, module string) bool { - return level <= l.GetLevel(module) -} - -func (l *moduleLeveled) Log(level Level, calldepth int, rec *Record) (err error) { - if l.IsEnabledFor(level, rec.Module) { - // TODO get rid of traces of formatter here. BackendFormatter should be used. - rec.formatter = l.getFormatterAndCacheCurrent() - err = l.backend.Log(level, calldepth+1, rec) - } - return -} - -func (l *moduleLeveled) getFormatterAndCacheCurrent() Formatter { - l.once.Do(func() { - if l.formatter == nil { - l.formatter = getFormatter() - } - }) - return l.formatter -} diff --git a/Godeps/_workspace/src/github.com/whyrusleeping/go-logging/level_test.go b/Godeps/_workspace/src/github.com/whyrusleeping/go-logging/level_test.go deleted file mode 100644 index c8f9a3733..000000000 --- a/Godeps/_workspace/src/github.com/whyrusleeping/go-logging/level_test.go +++ /dev/null @@ -1,76 +0,0 @@ -// Copyright 2013, Örjan Persson. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package logging - -import "testing" - -func TestLevelString(t *testing.T) { - // Make sure all levels can be converted from string -> constant -> string - for _, name := range levelNames { - level, err := LogLevel(name) - if err != nil { - t.Errorf("failed to get level: %v", err) - continue - } - - if level.String() != name { - t.Errorf("invalid level conversion: %v != %v", level, name) - } - } -} - -func TestLevelLogLevel(t *testing.T) { - tests := []struct { - expected Level - level string - }{ - {-1, "bla"}, - {INFO, "iNfO"}, - {ERROR, "error"}, - {WARNING, "warninG"}, - } - - for _, test := range tests { - level, err := LogLevel(test.level) - if err != nil { - if test.expected == -1 { - continue - } else { - t.Errorf("failed to convert %s: %s", test.level, err) - } - } - if test.expected != level { - t.Errorf("failed to convert %s to level: %s != %s", test.level, test.expected, level) - } - } -} - -func TestLevelModuleLevel(t *testing.T) { - backend := NewMemoryBackend(128) - - leveled := AddModuleLevel(backend) - leveled.SetLevel(NOTICE, "") - leveled.SetLevel(ERROR, "foo") - leveled.SetLevel(INFO, "foo.bar") - leveled.SetLevel(WARNING, "bar") - - expected := []struct { - level Level - module string - }{ - {NOTICE, ""}, - {NOTICE, "something"}, - {ERROR, "foo"}, - {INFO, "foo.bar"}, - {WARNING, "bar"}, - } - - for _, e := range expected { - actual := leveled.GetLevel(e.module) - if e.level != actual { - t.Errorf("unexpected level in %s: %s != %s", e.module, e.level, actual) - } - } -} diff --git a/Godeps/_workspace/src/github.com/whyrusleeping/go-logging/log.go b/Godeps/_workspace/src/github.com/whyrusleeping/go-logging/log.go deleted file mode 100644 index f009f8af5..000000000 --- a/Godeps/_workspace/src/github.com/whyrusleeping/go-logging/log.go +++ /dev/null @@ -1,80 +0,0 @@ -// Copyright 2013, Örjan Persson. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package logging - -import ( - "bytes" - "fmt" - "io" - "log" -) - -// TODO initialize here -var colors []string -var boldcolors []string - -type color int - -const ( - colorBlack = (iota + 30) - colorRed - colorGreen - colorYellow - colorBlue - colorMagenta - colorCyan - colorWhite -) - -// LogBackend utilizes the standard log module. -type LogBackend struct { - Logger *log.Logger - Color bool -} - -// NewLogBackend creates a new LogBackend. -func NewLogBackend(out io.Writer, prefix string, flag int) *LogBackend { - return &LogBackend{Logger: log.New(out, prefix, flag)} -} - -func (b *LogBackend) Log(level Level, calldepth int, rec *Record) error { - if b.Color { - buf := &bytes.Buffer{} - buf.Write([]byte(colors[level])) - buf.Write([]byte(rec.Formatted(calldepth + 1))) - buf.Write([]byte("\033[0m")) - // For some reason, the Go logger arbitrarily decided "2" was the correct - // call depth... - return b.Logger.Output(calldepth+2, buf.String()) - } else { - return b.Logger.Output(calldepth+2, rec.Formatted(calldepth+1)) - } - panic("should not be reached") -} - -func colorSeq(color color) string { - return fmt.Sprintf("\033[%dm", int(color)) -} - -func colorSeqBold(color color) string { - return fmt.Sprintf("\033[%d;1m", int(color)) -} - -func init() { - colors = []string{ - CRITICAL: colorSeq(colorMagenta), - ERROR: colorSeq(colorRed), - WARNING: colorSeq(colorYellow), - NOTICE: colorSeq(colorGreen), - DEBUG: colorSeq(colorCyan), - } - boldcolors = []string{ - CRITICAL: colorSeqBold(colorMagenta), - ERROR: colorSeqBold(colorRed), - WARNING: colorSeqBold(colorYellow), - NOTICE: colorSeqBold(colorGreen), - DEBUG: colorSeqBold(colorCyan), - } -} diff --git a/Godeps/_workspace/src/github.com/whyrusleeping/go-logging/log_test.go b/Godeps/_workspace/src/github.com/whyrusleeping/go-logging/log_test.go deleted file mode 100644 index 0ddcdf374..000000000 --- a/Godeps/_workspace/src/github.com/whyrusleeping/go-logging/log_test.go +++ /dev/null @@ -1,118 +0,0 @@ -// Copyright 2013, Örjan Persson. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package logging - -import ( - "bytes" - "io/ioutil" - "log" - "strings" - "testing" -) - -func TestLogCalldepth(t *testing.T) { - buf := &bytes.Buffer{} - SetBackend(NewLogBackend(buf, "", log.Lshortfile)) - SetFormatter(MustStringFormatter("%{shortfile} %{level} %{message}")) - - log := MustGetLogger("test") - log.Info("test filename") - - parts := strings.SplitN(buf.String(), " ", 2) - - // Verify that the correct filename is registered by the stdlib logger - if !strings.HasPrefix(parts[0], "log_test.go:") { - t.Errorf("incorrect filename: %s", parts[0]) - } - // Verify that the correct filename is registered by go-logging - if !strings.HasPrefix(parts[1], "log_test.go:") { - t.Errorf("incorrect filename: %s", parts[1]) - } -} - -func BenchmarkLogMemoryBackendIgnored(b *testing.B) { - backend := SetBackend(NewMemoryBackend(1024)) - backend.SetLevel(INFO, "") - RunLogBenchmark(b) -} - -func BenchmarkLogMemoryBackend(b *testing.B) { - backend := SetBackend(NewMemoryBackend(1024)) - backend.SetLevel(DEBUG, "") - RunLogBenchmark(b) -} - -func BenchmarkLogChannelMemoryBackend(b *testing.B) { - channelBackend := NewChannelMemoryBackend(1024) - backend := SetBackend(channelBackend) - backend.SetLevel(DEBUG, "") - RunLogBenchmark(b) - channelBackend.Flush() -} - -func BenchmarkLogLeveled(b *testing.B) { - backend := SetBackend(NewLogBackend(ioutil.Discard, "", 0)) - backend.SetLevel(INFO, "") - - RunLogBenchmark(b) -} - -func BenchmarkLogLogBackend(b *testing.B) { - backend := SetBackend(NewLogBackend(ioutil.Discard, "", 0)) - backend.SetLevel(DEBUG, "") - RunLogBenchmark(b) -} - -func BenchmarkLogLogBackendColor(b *testing.B) { - colorizer := NewLogBackend(ioutil.Discard, "", 0) - colorizer.Color = true - backend := SetBackend(colorizer) - backend.SetLevel(DEBUG, "") - RunLogBenchmark(b) -} - -func BenchmarkLogLogBackendStdFlags(b *testing.B) { - backend := SetBackend(NewLogBackend(ioutil.Discard, "", log.LstdFlags)) - backend.SetLevel(DEBUG, "") - RunLogBenchmark(b) -} - -func BenchmarkLogLogBackendLongFileFlag(b *testing.B) { - backend := SetBackend(NewLogBackend(ioutil.Discard, "", log.Llongfile)) - backend.SetLevel(DEBUG, "") - RunLogBenchmark(b) -} - -func RunLogBenchmark(b *testing.B) { - password := Password("foo") - log := MustGetLogger("test") - - b.ResetTimer() - for i := 0; i < b.N; i++ { - log.Debug("log line for %d and this is rectified: %s", i, password) - } -} - -func BenchmarkLogFixed(b *testing.B) { - backend := SetBackend(NewLogBackend(ioutil.Discard, "", 0)) - backend.SetLevel(DEBUG, "") - - RunLogBenchmarkFixedString(b) -} - -func BenchmarkLogFixedIgnored(b *testing.B) { - backend := SetBackend(NewLogBackend(ioutil.Discard, "", 0)) - backend.SetLevel(INFO, "") - RunLogBenchmarkFixedString(b) -} - -func RunLogBenchmarkFixedString(b *testing.B) { - log := MustGetLogger("test") - - b.ResetTimer() - for i := 0; i < b.N; i++ { - log.Debug("some random fixed text") - } -} diff --git a/Godeps/_workspace/src/github.com/whyrusleeping/go-logging/logger.go b/Godeps/_workspace/src/github.com/whyrusleeping/go-logging/logger.go deleted file mode 100644 index 858c382ea..000000000 --- a/Godeps/_workspace/src/github.com/whyrusleeping/go-logging/logger.go +++ /dev/null @@ -1,277 +0,0 @@ -// Copyright 2013, Örjan Persson. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package logging implements a logging infrastructure for Go. It supports -// different logging backends like syslog, file and memory. Multiple backends -// can be utilized with different log levels per backend and logger. -package logging - -import ( - "bytes" - "fmt" - "log" - "os" - "strings" - "sync/atomic" - "time" -) - -// Redactor is an interface for types that may contain sensitive information -// (like passwords), which shouldn't be printed to the log. The idea was found -// in relog as part of the vitness project. -type Redactor interface { - Redacted() interface{} -} - -// Redact returns a string of * having the same length as s. -func Redact(s string) string { - return strings.Repeat("*", len(s)) -} - -var ( - // Sequence number is incremented and utilized for all log records created. - sequenceNo uint64 - - // timeNow is a customizable for testing purposes. - timeNow = time.Now -) - -// Record represents a log record and contains the timestamp when the record -// was created, an increasing id, filename and line and finally the actual -// formatted log line. -type Record struct { - Id uint64 - Time time.Time - Module string - Level Level - - // message is kept as a pointer to have shallow copies update this once - // needed. - message *string - args []interface{} - fmt string - formatter Formatter - formatted string -} - -// Formatted returns the string-formatted version of a record. -func (r *Record) Formatted(calldepth int) string { - if r.formatted == "" { - var buf bytes.Buffer - r.formatter.Format(calldepth+1, r, &buf) - r.formatted = buf.String() - } - return r.formatted -} - -// Message returns a string message for outputting. Redacts any record args -// that implement the Redactor interface -func (r *Record) Message() string { - if r.message == nil { - // Redact the arguments that implements the Redactor interface - for i, arg := range r.args { - if redactor, ok := arg.(Redactor); ok == true { - r.args[i] = redactor.Redacted() - } - } - msg := fmt.Sprintf(r.fmt, r.args...) - r.message = &msg - } - return *r.message -} - -// Logger is a logging unit. It controls the flow of messages to a given -// (swappable) backend. -type Logger struct { - Module string - backend LeveledBackend - haveBackend bool - - // ExtraCallDepth can be used to add additional call depth when getting the - // calling function. This is normally used when wrapping a logger. - ExtraCalldepth int -} - -// SetBackend changes the backend of the logger. -func (l *Logger) SetBackend(backend LeveledBackend) { - l.backend = backend - l.haveBackend = true -} - -// GetLogger creates and returns a Logger object based on the module name. -// TODO call NewLogger and remove MustGetLogger? -func GetLogger(module string) (*Logger, error) { - return &Logger{Module: module}, nil -} - -// MustGetLogger is like GetLogger but panics if the logger can't be created. -// It simplifies safe initialization of a global logger for eg. a package. -func MustGetLogger(module string) *Logger { - logger, err := GetLogger(module) - if err != nil { - panic("logger: " + module + ": " + err.Error()) - } - return logger -} - -// Reset restores the internal state of the logging library. -func Reset() { - // TODO make a global Init() method to be less magic? or make it such that - // if there's no backends at all configured, we could use some tricks to - // automatically setup backends based if we have a TTY or not. - sequenceNo = 0 - b := SetBackend(NewLogBackend(os.Stderr, "", log.LstdFlags)) - b.SetLevel(DEBUG, "") - SetFormatter(DefaultFormatter) - timeNow = time.Now -} - -// InitForTesting is a convenient method when using logging in a test. Once -// called, the time will be frozen to January 1, 1970 UTC. -func InitForTesting(level Level) *MemoryBackend { - Reset() - - memoryBackend := NewMemoryBackend(10240) - - leveledBackend := AddModuleLevel(memoryBackend) - leveledBackend.SetLevel(level, "") - SetBackend(leveledBackend) - - timeNow = func() time.Time { - return time.Unix(0, 0).UTC() - } - return memoryBackend -} - -// IsEnabledFor returns true if the logger is enabled for the given level. -func (l *Logger) IsEnabledFor(level Level) bool { - return defaultBackend.IsEnabledFor(level, l.Module) -} - -func (l *Logger) log(lvl Level, format string, args ...interface{}) { - if !l.IsEnabledFor(lvl) { - return - } - - // Create the logging record and pass it in to the backend - record := &Record{ - Id: atomic.AddUint64(&sequenceNo, 1), - Time: timeNow(), - Module: l.Module, - Level: lvl, - fmt: format, - args: args, - } - - // TODO use channels to fan out the records to all backends? - // TODO in case of errors, do something (tricky) - - // calldepth=2 brings the stack up to the caller of the level - // methods, Info(), Fatal(), etc. - // ExtraCallDepth allows this to be extended further up the stack in case we - // are wrapping these methods, eg. to expose them package level - if l.haveBackend { - l.backend.Log(lvl, 2+l.ExtraCalldepth, record) - return - } - - defaultBackend.Log(lvl, 2+l.ExtraCalldepth, record) -} - -// Fatal is equivalent to l.Critical(fmt.Sprint()) followed by a call to os.Exit(1). -func (l *Logger) Fatal(args ...interface{}) { - s := fmt.Sprint(args...) - l.log(CRITICAL, "%s", s) - os.Exit(1) -} - -// Fatalf is equivalent to l.Critical followed by a call to os.Exit(1). -func (l *Logger) Fatalf(format string, args ...interface{}) { - l.log(CRITICAL, format, args...) - os.Exit(1) -} - -// Panic is equivalent to l.Critical(fmt.Sprint()) followed by a call to panic(). -func (l *Logger) Panic(args ...interface{}) { - s := fmt.Sprint(args...) - l.log(CRITICAL, "%s", s) - panic(s) -} - -// Panicf is equivalent to l.Critical followed by a call to panic(). -func (l *Logger) Panicf(format string, args ...interface{}) { - s := fmt.Sprintf(format, args...) - l.log(CRITICAL, "%s", s) - panic(s) -} - -// Critical logs a message using CRITICAL as log level. (fmt.Sprint()) -func (l *Logger) Critical(args ...interface{}) { - s := fmt.Sprint(args...) - l.log(CRITICAL, "%s", s) -} - -// Criticalf logs a message using CRITICAL as log level. -func (l *Logger) Criticalf(format string, args ...interface{}) { - l.log(CRITICAL, format, args...) -} - -// Error logs a message using ERROR as log level. (fmt.Sprint()) -func (l *Logger) Error(args ...interface{}) { - s := fmt.Sprint(args...) - l.log(ERROR, "%s", s) -} - -// Errorf logs a message using ERROR as log level. -func (l *Logger) Errorf(format string, args ...interface{}) { - l.log(ERROR, format, args...) -} - -// Warning logs a message using WARNING as log level. -func (l *Logger) Warning(args ...interface{}) { - s := fmt.Sprint(args...) - l.log(WARNING, "%s", s) -} - -// Warningf logs a message using WARNING as log level. -func (l *Logger) Warningf(format string, args ...interface{}) { - l.log(WARNING, format, args...) -} - -// Notice logs a message using NOTICE as log level. -func (l *Logger) Notice(args ...interface{}) { - s := fmt.Sprint(args...) - l.log(NOTICE, "%s", s) -} - -// Noticef logs a message using NOTICE as log level. -func (l *Logger) Noticef(format string, args ...interface{}) { - l.log(NOTICE, format, args...) -} - -// Info logs a message using INFO as log level. -func (l *Logger) Info(args ...interface{}) { - s := fmt.Sprint(args...) - l.log(INFO, "%s", s) -} - -// Infof logs a message using INFO as log level. -func (l *Logger) Infof(format string, args ...interface{}) { - l.log(INFO, format, args...) -} - -// Debug logs a message using DEBUG as log level. -func (l *Logger) Debug(args ...interface{}) { - s := fmt.Sprint(args...) - l.log(DEBUG, "%s", s) -} - -// Debugf logs a message using DEBUG as log level. -func (l *Logger) Debugf(format string, args ...interface{}) { - l.log(DEBUG, format, args...) -} - -func init() { - Reset() -} diff --git a/Godeps/_workspace/src/github.com/whyrusleeping/go-logging/logger_test.go b/Godeps/_workspace/src/github.com/whyrusleeping/go-logging/logger_test.go deleted file mode 100644 index 2de58a6a8..000000000 --- a/Godeps/_workspace/src/github.com/whyrusleeping/go-logging/logger_test.go +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright 2013, Örjan Persson. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package logging - -import "testing" - -type Password string - -func (p Password) Redacted() interface{} { - return Redact(string(p)) -} - -func TestSequenceNoOverflow(t *testing.T) { - // Forcefully set the next sequence number to the maximum - backend := InitForTesting(DEBUG) - sequenceNo = ^uint64(0) - - log := MustGetLogger("test") - log.Debug("test") - - if MemoryRecordN(backend, 0).Id != 0 { - t.Errorf("Unexpected sequence no: %v", MemoryRecordN(backend, 0).Id) - } -} - -func TestRedact(t *testing.T) { - backend := InitForTesting(DEBUG) - password := Password("123456") - log := MustGetLogger("test") - log.Debugf("foo %s", password) - if "foo ******" != MemoryRecordN(backend, 0).Formatted(0) { - t.Errorf("redacted line: %v", MemoryRecordN(backend, 0)) - } -} - -func TestPrivateBackend(t *testing.T) { - stdBackend := InitForTesting(DEBUG) - log := MustGetLogger("test") - privateBackend := NewMemoryBackend(10240) - lvlBackend := AddModuleLevel(privateBackend) - lvlBackend.SetLevel(DEBUG, "") - log.SetBackend(lvlBackend) - log.Debug("to private backend") - if stdBackend.size > 0 { - t.Errorf("something in stdBackend, size of backend: %d", stdBackend.size) - } - if "to private baсkend" == MemoryRecordN(privateBackend, 0).Formatted(0) { - t.Errorf("logged to defaultBackend: %s", MemoryRecordN(privateBackend, 0)) - } - -} diff --git a/Godeps/_workspace/src/github.com/whyrusleeping/go-logging/memory.go b/Godeps/_workspace/src/github.com/whyrusleeping/go-logging/memory.go deleted file mode 100644 index c59b92dde..000000000 --- a/Godeps/_workspace/src/github.com/whyrusleeping/go-logging/memory.go +++ /dev/null @@ -1,217 +0,0 @@ -// Copyright 2013, Örjan Persson. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package logging - -import ( - "sync" - "sync/atomic" - "unsafe" -) - -// TODO pick one of the memory backends and stick with it or share interface. - -// Node is a record node pointing to an optional next node. -type node struct { - next *node - Record *Record -} - -// Next returns the next record node. If there's no node available, it will -// return nil. -func (n *node) Next() *node { - return n.next -} - -// MemoryBackend is a simple memory based logging backend that will not produce -// any output but merly keep records, up to the given size, in memory. -type MemoryBackend struct { - size int32 - maxSize int32 - head, tail unsafe.Pointer -} - -// NewMemoryBackend creates a simple in-memory logging backend. -func NewMemoryBackend(size int) *MemoryBackend { - return &MemoryBackend{maxSize: int32(size)} -} - -// Log implements the Log method required by Backend. -func (b *MemoryBackend) Log(level Level, calldepth int, rec *Record) error { - var size int32 - - n := &node{Record: rec} - np := unsafe.Pointer(n) - - // Add the record to the tail. If there's no records available, tail and - // head will both be nil. When we successfully set the tail and the previous - // value was nil, it's safe to set the head to the current value too. - for { - tailp := b.tail - swapped := atomic.CompareAndSwapPointer( - &b.tail, - tailp, - np, - ) - if swapped == true { - if tailp == nil { - b.head = np - } else { - (*node)(tailp).next = n - } - size = atomic.AddInt32(&b.size, 1) - break - } - } - - // Since one record was added, we might have overflowed the list. Remove - // a record if that is the case. The size will fluctate a bit, but - // eventual consistent. - if b.maxSize > 0 && size > b.maxSize { - for { - headp := b.head - head := (*node)(b.head) - if head.next == nil { - break - } - swapped := atomic.CompareAndSwapPointer( - &b.head, - headp, - unsafe.Pointer(head.next), - ) - if swapped == true { - atomic.AddInt32(&b.size, -1) - break - } - } - } - return nil -} - -// Head returns the oldest record node kept in memory. It can be used to -// iterate over records, one by one, up to the last record. -// -// Note: new records can get added while iterating. Hence the number of records -// iterated over might be larger than the maximum size. -func (b *MemoryBackend) Head() *node { - return (*node)(b.head) -} - -type event int - -const ( - eventFlush event = iota - eventStop -) - -// ChannelMemoryBackend is very similar to the MemoryBackend, except that it -// internally utilizes a channel. -type ChannelMemoryBackend struct { - maxSize int - size int - incoming chan *Record - events chan event - mu sync.Mutex - running bool - flushWg sync.WaitGroup - stopWg sync.WaitGroup - head, tail *node -} - -// NewChannelMemoryBackend creates a simple in-memory logging backend which -// utilizes a go channel for communication. -// -// Start will automatically be called by this function. -func NewChannelMemoryBackend(size int) *ChannelMemoryBackend { - backend := &ChannelMemoryBackend{ - maxSize: size, - incoming: make(chan *Record, 1024), - events: make(chan event), - } - backend.Start() - return backend -} - -// Start launches the internal goroutine which starts processing data from the -// input channel. -func (b *ChannelMemoryBackend) Start() { - b.mu.Lock() - defer b.mu.Unlock() - - // Launch the goroutine unless it's already running. - if b.running != true { - b.running = true - b.stopWg.Add(1) - go b.process() - } -} - -func (b *ChannelMemoryBackend) process() { - defer b.stopWg.Done() - for { - select { - case rec := <-b.incoming: - b.insertRecord(rec) - case e := <-b.events: - switch e { - case eventStop: - return - case eventFlush: - for len(b.incoming) > 0 { - b.insertRecord(<-b.incoming) - } - b.flushWg.Done() - } - } - } -} - -func (b *ChannelMemoryBackend) insertRecord(rec *Record) { - prev := b.tail - b.tail = &node{Record: rec} - if prev == nil { - b.head = b.tail - } else { - prev.next = b.tail - } - - if b.maxSize > 0 && b.size >= b.maxSize { - b.head = b.head.next - } else { - b.size += 1 - } -} - -// Flush waits until all records in the buffered channel have been processed. -func (b *ChannelMemoryBackend) Flush() { - b.flushWg.Add(1) - b.events <- eventFlush - b.flushWg.Wait() -} - -// Stop signals the internal goroutine to exit and waits until it have. -func (b *ChannelMemoryBackend) Stop() { - b.mu.Lock() - if b.running == true { - b.running = false - b.events <- eventStop - } - b.mu.Unlock() - b.stopWg.Wait() -} - -// Log implements the Log method required by Backend. -func (b *ChannelMemoryBackend) Log(level Level, calldepth int, rec *Record) error { - b.incoming <- rec - return nil -} - -// Head returns the oldest record node kept in memory. It can be used to -// iterate over records, one by one, up to the last record. -// -// Note: new records can get added while iterating. Hence the number of records -// iterated over might be larger than the maximum size. -func (b *ChannelMemoryBackend) Head() *node { - return b.head -} diff --git a/Godeps/_workspace/src/github.com/whyrusleeping/go-logging/memory_test.go b/Godeps/_workspace/src/github.com/whyrusleeping/go-logging/memory_test.go deleted file mode 100644 index c2fe6c822..000000000 --- a/Godeps/_workspace/src/github.com/whyrusleeping/go-logging/memory_test.go +++ /dev/null @@ -1,117 +0,0 @@ -// Copyright 2013, Örjan Persson. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package logging - -import ( - "strconv" - "testing" -) - -// TODO share more code between these tests -func MemoryRecordN(b *MemoryBackend, n int) *Record { - node := b.Head() - for i := 0; i < n; i++ { - if node == nil { - break - } - node = node.Next() - } - if node == nil { - return nil - } - return node.Record -} - -func ChannelMemoryRecordN(b *ChannelMemoryBackend, n int) *Record { - b.Flush() - node := b.Head() - for i := 0; i < n; i++ { - if node == nil { - break - } - node = node.Next() - } - if node == nil { - return nil - } - return node.Record -} - -func TestMemoryBackend(t *testing.T) { - backend := NewMemoryBackend(8) - SetBackend(backend) - - log := MustGetLogger("test") - - if nil != MemoryRecordN(backend, 0) || 0 != backend.size { - t.Errorf("memory level: %d", backend.size) - } - - // Run 13 times, the resulting vector should be [5..12] - for i := 0; i < 13; i++ { - log.Infof("%d", i) - } - - if 8 != backend.size { - t.Errorf("record length: %d", backend.size) - } - record := MemoryRecordN(backend, 0) - if "5" != record.Formatted(0) { - t.Errorf("unexpected start: %s", record.Formatted(0)) - } - for i := 0; i < 8; i++ { - record = MemoryRecordN(backend, i) - if strconv.Itoa(i+5) != record.Formatted(0) { - t.Errorf("unexpected record: %v", record.Formatted(0)) - } - } - record = MemoryRecordN(backend, 7) - if "12" != record.Formatted(0) { - t.Errorf("unexpected end: %s", record.Formatted(0)) - } - record = MemoryRecordN(backend, 8) - if nil != record { - t.Errorf("unexpected eof: %s", record.Formatted(0)) - } -} - -func TestChannelMemoryBackend(t *testing.T) { - backend := NewChannelMemoryBackend(8) - SetBackend(backend) - - log := MustGetLogger("test") - - if nil != ChannelMemoryRecordN(backend, 0) || 0 != backend.size { - t.Errorf("memory level: %d", backend.size) - } - - // Run 13 times, the resulting vector should be [5..12] - for i := 0; i < 13; i++ { - log.Infof("%d", i) - } - backend.Flush() - - if 8 != backend.size { - t.Errorf("record length: %d", backend.size) - } - record := ChannelMemoryRecordN(backend, 0) - if "5" != record.Formatted(0) { - t.Errorf("unexpected start: %s", record.Formatted(0)) - } - for i := 0; i < 8; i++ { - record = ChannelMemoryRecordN(backend, i) - if strconv.Itoa(i+5) != record.Formatted(0) { - t.Errorf("unexpected record: %v", record.Formatted(0)) - } - } - record = ChannelMemoryRecordN(backend, 7) - if "12" != record.Formatted(0) { - t.Errorf("unexpected end: %s", record.Formatted(0)) - } - record = ChannelMemoryRecordN(backend, 8) - if nil != record { - t.Errorf("unexpected eof: %s", record.Formatted(0)) - } -} diff --git a/Godeps/_workspace/src/github.com/whyrusleeping/go-logging/multi.go b/Godeps/_workspace/src/github.com/whyrusleeping/go-logging/multi.go deleted file mode 100644 index 3731653e6..000000000 --- a/Godeps/_workspace/src/github.com/whyrusleeping/go-logging/multi.go +++ /dev/null @@ -1,65 +0,0 @@ -// Copyright 2013, Örjan Persson. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package logging - -// TODO remove Level stuff from the multi logger. Do one thing. - -// multiLogger is a log multiplexer which can be used to utilize multiple log -// backends at once. -type multiLogger struct { - backends []LeveledBackend -} - -// MultiLogger creates a logger which contain multiple loggers. -func MultiLogger(backends ...Backend) LeveledBackend { - var leveledBackends []LeveledBackend - for _, backend := range backends { - leveledBackends = append(leveledBackends, AddModuleLevel(backend)) - } - return &multiLogger{leveledBackends} -} - -// Log passes the log record to all backends. -func (b *multiLogger) Log(level Level, calldepth int, rec *Record) (err error) { - for _, backend := range b.backends { - if backend.IsEnabledFor(level, rec.Module) { - // Shallow copy of the record for the formatted cache on Record and get the - // record formatter from the backend. - r2 := *rec - if e := backend.Log(level, calldepth+1, &r2); e != nil { - err = e - } - } - } - return -} - -// GetLevel returns the highest level enabled by all backends. -func (b *multiLogger) GetLevel(module string) Level { - var level Level - for _, backend := range b.backends { - if backendLevel := backend.GetLevel(module); backendLevel > level { - level = backendLevel - } - } - return level -} - -// SetLevel propagates the same level to all backends. -func (b *multiLogger) SetLevel(level Level, module string) { - for _, backend := range b.backends { - backend.SetLevel(level, module) - } -} - -// IsEnabledFor returns true if any of the backends are enabled for it. -func (b *multiLogger) IsEnabledFor(level Level, module string) bool { - for _, backend := range b.backends { - if backend.IsEnabledFor(level, module) { - return true - } - } - return false -} diff --git a/Godeps/_workspace/src/github.com/whyrusleeping/go-logging/multi_test.go b/Godeps/_workspace/src/github.com/whyrusleeping/go-logging/multi_test.go deleted file mode 100644 index e1da5e3d5..000000000 --- a/Godeps/_workspace/src/github.com/whyrusleeping/go-logging/multi_test.go +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright 2013, Örjan Persson. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package logging - -import "testing" - -func TestMultiLogger(t *testing.T) { - log1 := NewMemoryBackend(8) - log2 := NewMemoryBackend(8) - SetBackend(MultiLogger(log1, log2)) - - log := MustGetLogger("test") - log.Debug("log") - - if "log" != MemoryRecordN(log1, 0).Formatted(0) { - t.Errorf("log1: %v", MemoryRecordN(log1, 0).Formatted(0)) - } - if "log" != MemoryRecordN(log2, 0).Formatted(0) { - t.Errorf("log2: %v", MemoryRecordN(log2, 0).Formatted(0)) - } -} - -func TestMultiLoggerLevel(t *testing.T) { - log1 := NewMemoryBackend(8) - log2 := NewMemoryBackend(8) - - leveled1 := AddModuleLevel(log1) - leveled2 := AddModuleLevel(log2) - - multi := MultiLogger(leveled1, leveled2) - multi.SetLevel(ERROR, "test") - SetBackend(multi) - - log := MustGetLogger("test") - log.Notice("log") - - if nil != MemoryRecordN(log1, 0) || nil != MemoryRecordN(log2, 0) { - t.Errorf("unexpected log record") - } - - leveled1.SetLevel(DEBUG, "test") - log.Notice("log") - if "log" != MemoryRecordN(log1, 0).Formatted(0) { - t.Errorf("log1 not received") - } - if nil != MemoryRecordN(log2, 0) { - t.Errorf("log2 received") - } -} diff --git a/Godeps/_workspace/src/github.com/whyrusleeping/go-logging/syslog.go b/Godeps/_workspace/src/github.com/whyrusleeping/go-logging/syslog.go deleted file mode 100644 index 9a5c8f5d3..000000000 --- a/Godeps/_workspace/src/github.com/whyrusleeping/go-logging/syslog.go +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright 2013, Örjan Persson. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//+build !windows,!plan9 - -package logging - -import "log/syslog" - -// SyslogBackend is a simple logger to syslog backend. It automatically maps -// the internal log levels to appropriate syslog log levels. -type SyslogBackend struct { - Writer *syslog.Writer -} - -// NewSyslogBackend connects to the syslog daemon using UNIX sockets with the -// given prefix. If prefix is not given, the prefix will be derived from the -// launched command. -func NewSyslogBackend(prefix string) (b *SyslogBackend, err error) { - var w *syslog.Writer - w, err = syslog.New(syslog.LOG_CRIT, prefix) - return &SyslogBackend{w}, err -} - -// NewSyslogBackendPriority is the same as NewSyslogBackend, but with custom -// syslog priority, like syslog.LOG_LOCAL3|syslog.LOG_DEBUG etc. -func NewSyslogBackendPriority(prefix string, priority syslog.Priority) (b *SyslogBackend, err error) { - var w *syslog.Writer - w, err = syslog.New(priority, prefix) - return &SyslogBackend{w}, err -} - -func (b *SyslogBackend) Log(level Level, calldepth int, rec *Record) error { - line := rec.Formatted(calldepth + 1) - switch level { - case CRITICAL: - return b.Writer.Crit(line) - case ERROR: - return b.Writer.Err(line) - case WARNING: - return b.Writer.Warning(line) - case NOTICE: - return b.Writer.Notice(line) - case INFO: - return b.Writer.Info(line) - case DEBUG: - return b.Writer.Debug(line) - default: - } - panic("unhandled log level") -} diff --git a/cmd/ipfs/main.go b/cmd/ipfs/main.go index 88562172b..9183cddcc 100644 --- a/cmd/ipfs/main.go +++ b/cmd/ipfs/main.go @@ -465,7 +465,7 @@ func startProfiling() (func(), error) { for _ = range time.NewTicker(time.Second * 30).C { err := writeHeapProfileToFile() if err != nil { - log.Critical(err) + log.Error(err) } } }() diff --git a/core/commands/log.go b/core/commands/log.go index 8fb80f8b3..aa819c625 100644 --- a/core/commands/log.go +++ b/core/commands/log.go @@ -45,7 +45,7 @@ output of a running daemon. // TODO use a different keyword for 'all' because all can theoretically // clash with a subsystem name cmds.StringArg("subsystem", true, false, fmt.Sprintf("the subsystem logging identifier. Use '%s' for all subsystems.", logAllKeyword)), - cmds.StringArg("level", true, false, "one of: debug, info, notice, warning, error, critical"), + cmds.StringArg("level", true, false, "one of: debug, info, warning, error, fatal, panic"), }, Run: func(req cmds.Request, res cmds.Response) { diff --git a/exchange/bitswap/bitswap.go b/exchange/bitswap/bitswap.go index bed1d3a47..53c89a7d9 100644 --- a/exchange/bitswap/bitswap.go +++ b/exchange/bitswap/bitswap.go @@ -280,7 +280,7 @@ func (bs *Bitswap) ReceiveMessage(ctx context.Context, p peer.ID, incoming bsmsg var keys []key.Key for _, block := range iblocks { if _, found := bs.wm.wl.Contains(block.Key()); !found { - log.Notice("received un-asked-for block: %s", block) + log.Info("received un-asked-for block: %s", block) continue } keys = append(keys, block.Key()) @@ -297,7 +297,7 @@ func (bs *Bitswap) ReceiveMessage(ctx context.Context, p peer.ID, incoming bsmsg has, err := bs.blockstore.Has(b.Key()) if err != nil { bs.counterLk.Unlock() - log.Noticef("blockstore.Has error: %s", err) + log.Infof("blockstore.Has error: %s", err) return } if err == nil && has { diff --git a/exchange/bitswap/testutils.go b/exchange/bitswap/testutils.go index 47930de69..91fdece7f 100644 --- a/exchange/bitswap/testutils.go +++ b/exchange/bitswap/testutils.go @@ -50,7 +50,7 @@ func (g *SessionGenerator) Next() Instance { } func (g *SessionGenerator) Instances(n int) []Instance { - instances := make([]Instance, 0) + var instances []Instance for j := 0; j < n; j++ { inst := g.Next() instances = append(instances, inst) @@ -87,12 +87,12 @@ func (i *Instance) SetBlockstoreLatency(t time.Duration) time.Duration { // just a much better idea. func session(ctx context.Context, net tn.Network, p testutil.Identity) Instance { bsdelay := delay.Fixed(0) - const kWriteCacheElems = 100 + const writeCacheElems = 100 adapter := net.Adapter(p) dstore := ds_sync.MutexWrap(datastore2.WithDelay(ds.NewMapDatastore(), bsdelay)) - bstore, err := blockstore.WriteCached(blockstore.NewBlockstore(ds_sync.MutexWrap(dstore)), kWriteCacheElems) + bstore, err := blockstore.WriteCached(blockstore.NewBlockstore(ds_sync.MutexWrap(dstore)), writeCacheElems) if err != nil { panic(err.Error()) // FIXME perhaps change signature and return error. } diff --git a/exchange/bitswap/wantmanager.go b/exchange/bitswap/wantmanager.go index 32c42776c..a8eeb58e2 100644 --- a/exchange/bitswap/wantmanager.go +++ b/exchange/bitswap/wantmanager.go @@ -96,7 +96,7 @@ func (pm *WantManager) SendBlock(ctx context.Context, env *engine.Envelope) { log.Infof("Sending block %s to %s", env.Peer, env.Block) err := pm.network.SendMessage(ctx, env.Peer, msg) if err != nil { - log.Noticef("sendblock error: %s", err) + log.Infof("sendblock error: %s", err) } } @@ -153,7 +153,7 @@ func (mq *msgQueue) doWork(ctx context.Context) { err := mq.network.ConnectTo(conctx, mq.p) if err != nil { - log.Noticef("cant connect to peer %s: %s", mq.p, err) + log.Infof("cant connect to peer %s: %s", mq.p, err) // TODO: cant connect, what now? return } @@ -174,7 +174,7 @@ func (mq *msgQueue) doWork(ctx context.Context) { // send wantlist updates err = mq.network.SendMessage(sendctx, mq.p, wlm) if err != nil { - log.Noticef("bitswap send error: %s", err) + log.Infof("bitswap send error: %s", err) // TODO: what do we do if this fails? return } diff --git a/fuse/ipns/ipns_unix.go b/fuse/ipns/ipns_unix.go index b75b44444..e01b03136 100644 --- a/fuse/ipns/ipns_unix.go +++ b/fuse/ipns/ipns_unix.go @@ -462,10 +462,10 @@ func (dir *Directory) Rename(ctx context.Context, req *fuse.RenameRequest, newDi return err } case *File: - log.Critical("Cannot move node into a file!") + log.Error("Cannot move node into a file!") return fuse.EPERM default: - log.Critical("Unknown node type for rename target dir!") + log.Error("Unknown node type for rename target dir!") return errors.New("Unknown fs node type!") } return nil diff --git a/ipnsfs/system.go b/ipnsfs/system.go index b6e2a430f..b1e4998b2 100644 --- a/ipnsfs/system.go +++ b/ipnsfs/system.go @@ -80,7 +80,7 @@ func (fs *Filesystem) Close() error { defer wg.Done() err := r.Publish(context.TODO()) if err != nil { - log.Notice(err) + log.Info(err) return } }(r) @@ -285,7 +285,7 @@ func (np *Republisher) Run(ctx context.Context) { log.Info("Publishing Changes!") err := np.root.Publish(ctx) if err != nil { - log.Critical("republishRoot error: %s", err) + log.Error("republishRoot error: %s", err) } case <-ctx.Done(): diff --git a/p2p/test/util/key.go b/p2p/test/util/key.go index b3fc5dd6d..2be7a3356 100644 --- a/p2p/test/util/key.go +++ b/p2p/test/util/key.go @@ -24,7 +24,7 @@ type TestBogusPrivateKey []byte type TestBogusPublicKey []byte func (pk TestBogusPublicKey) Verify(data, sig []byte) (bool, error) { - log.Criticalf("TestBogusPublicKey.Verify -- this better be a test!") + log.Errorf("TestBogusPublicKey.Verify -- this better be a test!") return bytes.Equal(data, reverse(sig)), nil } @@ -33,7 +33,7 @@ func (pk TestBogusPublicKey) Bytes() ([]byte, error) { } func (pk TestBogusPublicKey) Encrypt(b []byte) ([]byte, error) { - log.Criticalf("TestBogusPublicKey.Encrypt -- this better be a test!") + log.Errorf("TestBogusPublicKey.Encrypt -- this better be a test!") return reverse(b), nil } @@ -51,7 +51,7 @@ func (sk TestBogusPrivateKey) GenSecret() []byte { } func (sk TestBogusPrivateKey) Sign(message []byte) ([]byte, error) { - log.Criticalf("TestBogusPrivateKey.Sign -- this better be a test!") + log.Errorf("TestBogusPrivateKey.Sign -- this better be a test!") return reverse(message), nil } @@ -60,7 +60,7 @@ func (sk TestBogusPrivateKey) GetPublic() ic.PubKey { } func (sk TestBogusPrivateKey) Decrypt(b []byte) ([]byte, error) { - log.Criticalf("TestBogusPrivateKey.Decrypt -- this better be a test!") + log.Errorf("TestBogusPrivateKey.Decrypt -- this better be a test!") return reverse(b), nil } diff --git a/routing/dht/dht_test.go b/routing/dht/dht_test.go index a6eb41a77..83c3b2b20 100644 --- a/routing/dht/dht_test.go +++ b/routing/dht/dht_test.go @@ -773,7 +773,7 @@ func TestConnectCollision(t *testing.T) { runTimes := 10 for rtime := 0; rtime < runTimes; rtime++ { - log.Notice("Running Time: ", rtime) + log.Info("Running Time: ", rtime) ctx := context.Background() diff --git a/routing/dht/handlers.go b/routing/dht/handlers.go index b3db5d87e..36a92a251 100644 --- a/routing/dht/handlers.go +++ b/routing/dht/handlers.go @@ -89,7 +89,7 @@ func (dht *IpfsDHT) handleGetValue(ctx context.Context, p peer.ID, pmes *pb.Mess for _, pi := range closerinfos { log.Debugf("handleGetValue returning closer peer: '%s'", pi.ID) if len(pi.Addrs) < 1 { - log.Criticalf(`no addresses on peer being sent! + log.Errorf(`no addresses on peer being sent! [local:%s] [sending:%s] [remote:%s]`, dht.self, pi.ID, p) diff --git a/routing/supernode/proxy/standard.go b/routing/supernode/proxy/standard.go index b85b053e5..fe723409e 100644 --- a/routing/supernode/proxy/standard.go +++ b/routing/supernode/proxy/standard.go @@ -50,7 +50,7 @@ func (px *standard) Bootstrap(ctx context.Context) error { cxns = append(cxns, info) } if len(cxns) == 0 { - log.Critical("unable to bootstrap to any supernode routers") + log.Error("unable to bootstrap to any supernode routers") } else { log.Infof("bootstrapped to %d supernode routers: %s", len(cxns), cxns) } diff --git a/test/integration/addcat_test.go b/test/integration/addcat_test.go index 62c8944fd..c81672e6c 100644 --- a/test/integration/addcat_test.go +++ b/test/integration/addcat_test.go @@ -61,7 +61,7 @@ func TestDegenerateSlowRouting(t *testing.T) { func Test100MBMacbookCoastToCoast(t *testing.T) { SkipUnlessEpic(t) - conf := testutil.LatencyConfig{}.Network_NYtoSF().Blockstore_SlowSSD2014().Routing_Slow() + conf := testutil.LatencyConfig{}.NetworkNYtoSF().BlockstoreSlowSSD2014().RoutingSlow() if err := DirectAddCat(RandomBytes(100*1024*1024), conf); err != nil { t.Fatal(err) } diff --git a/test/integration/bench_test.go b/test/integration/bench_test.go index b159b912d..eaadf2702 100644 --- a/test/integration/bench_test.go +++ b/test/integration/bench_test.go @@ -21,7 +21,7 @@ func benchmarkAddCat(numBytes int64, conf testutil.LatencyConfig, b *testing.B) } } -var instant = testutil.LatencyConfig{}.All_Instantaneous() +var instant = testutil.LatencyConfig{}.AllInstantaneous() func BenchmarkInstantaneousAddCat1KB(b *testing.B) { benchmarkAddCat(1*unit.KB, instant, b) } func BenchmarkInstantaneousAddCat1MB(b *testing.B) { benchmarkAddCat(1*unit.MB, instant, b) } @@ -34,7 +34,7 @@ func BenchmarkInstantaneousAddCat64MB(b *testing.B) { benchmarkAddCat(64*unit.M func BenchmarkInstantaneousAddCat128MB(b *testing.B) { benchmarkAddCat(128*unit.MB, instant, b) } func BenchmarkInstantaneousAddCat256MB(b *testing.B) { benchmarkAddCat(256*unit.MB, instant, b) } -var routing = testutil.LatencyConfig{}.Routing_Slow() +var routing = testutil.LatencyConfig{}.RoutingSlow() func BenchmarkRoutingSlowAddCat1MB(b *testing.B) { benchmarkAddCat(1*unit.MB, routing, b) } func BenchmarkRoutingSlowAddCat2MB(b *testing.B) { benchmarkAddCat(2*unit.MB, routing, b) } @@ -47,7 +47,7 @@ func BenchmarkRoutingSlowAddCat128MB(b *testing.B) { benchmarkAddCat(128*unit.MB func BenchmarkRoutingSlowAddCat256MB(b *testing.B) { benchmarkAddCat(256*unit.MB, routing, b) } func BenchmarkRoutingSlowAddCat512MB(b *testing.B) { benchmarkAddCat(512*unit.MB, routing, b) } -var network = testutil.LatencyConfig{}.Network_NYtoSF() +var network = testutil.LatencyConfig{}.NetworkNYtoSF() func BenchmarkNetworkSlowAddCat1MB(b *testing.B) { benchmarkAddCat(1*unit.MB, network, b) } func BenchmarkNetworkSlowAddCat2MB(b *testing.B) { benchmarkAddCat(2*unit.MB, network, b) } @@ -59,7 +59,7 @@ func BenchmarkNetworkSlowAddCat64MB(b *testing.B) { benchmarkAddCat(64*unit.MB, func BenchmarkNetworkSlowAddCat128MB(b *testing.B) { benchmarkAddCat(128*unit.MB, network, b) } func BenchmarkNetworkSlowAddCat256MB(b *testing.B) { benchmarkAddCat(256*unit.MB, network, b) } -var hdd = testutil.LatencyConfig{}.Blockstore_7200RPM() +var hdd = testutil.LatencyConfig{}.Blockstore7200RPM() func BenchmarkBlockstoreSlowAddCat1MB(b *testing.B) { benchmarkAddCat(1*unit.MB, hdd, b) } func BenchmarkBlockstoreSlowAddCat2MB(b *testing.B) { benchmarkAddCat(2*unit.MB, hdd, b) } @@ -71,7 +71,7 @@ func BenchmarkBlockstoreSlowAddCat64MB(b *testing.B) { benchmarkAddCat(64*unit. func BenchmarkBlockstoreSlowAddCat128MB(b *testing.B) { benchmarkAddCat(128*unit.MB, hdd, b) } func BenchmarkBlockstoreSlowAddCat256MB(b *testing.B) { benchmarkAddCat(256*unit.MB, hdd, b) } -var mixed = testutil.LatencyConfig{}.Network_NYtoSF().Blockstore_SlowSSD2014().Routing_Slow() +var mixed = testutil.LatencyConfig{}.NetworkNYtoSF().BlockstoreSlowSSD2014().RoutingSlow() func BenchmarkMixedAddCat1MBXX(b *testing.B) { benchmarkAddCat(1*unit.MB, mixed, b) } func BenchmarkMixedAddCat2MBXX(b *testing.B) { benchmarkAddCat(2*unit.MB, mixed, b) } diff --git a/test/integration/three_legged_cat_test.go b/test/integration/three_legged_cat_test.go index 26a7924b6..45b05f769 100644 --- a/test/integration/three_legged_cat_test.go +++ b/test/integration/three_legged_cat_test.go @@ -55,7 +55,7 @@ func TestThreeLeggedCatDegenerateSlowRouting(t *testing.T) { func TestThreeLeggedCat100MBMacbookCoastToCoast(t *testing.T) { SkipUnlessEpic(t) - conf := testutil.LatencyConfig{}.Network_NYtoSF().Blockstore_SlowSSD2014().Routing_Slow() + conf := testutil.LatencyConfig{}.NetworkNYtoSF().BlockstoreSlowSSD2014().RoutingSlow() if err := RunThreeLeggedCat(RandomBytes(100*unit.MB), conf); err != nil { t.Fatal(err) } diff --git a/thirdparty/eventlog/log.go b/thirdparty/eventlog/log.go index 21dcfa39c..6fab7383c 100644 --- a/thirdparty/eventlog/log.go +++ b/thirdparty/eventlog/log.go @@ -11,8 +11,6 @@ import ( // StandardLogger provides API compatibility with standard printf loggers // eg. go-logging type StandardLogger interface { - Critical(args ...interface{}) - Criticalf(format string, args ...interface{}) Debug(args ...interface{}) Debugf(format string, args ...interface{}) Error(args ...interface{}) @@ -21,8 +19,6 @@ type StandardLogger interface { Fatalf(format string, args ...interface{}) Info(args ...interface{}) Infof(format string, args ...interface{}) - Notice(args ...interface{}) - Noticef(format string, args ...interface{}) Panic(args ...interface{}) Panicf(format string, args ...interface{}) Warning(args ...interface{}) diff --git a/thirdparty/eventlog/loggable.go b/thirdparty/eventlog/loggable.go index 3f954ccc1..27ffd8048 100644 --- a/thirdparty/eventlog/loggable.go +++ b/thirdparty/eventlog/loggable.go @@ -11,7 +11,7 @@ func (l LoggableMap) Loggable() map[string]interface{} { return l } -// Loggable converts a func into a Loggable +// LoggableF converts a func into a Loggable type LoggableF func() map[string]interface{} func (l LoggableF) Loggable() map[string]interface{} { diff --git a/thirdparty/notifier/notifier.go b/thirdparty/notifier/notifier.go index 7bfdbb22a..5d5a830b0 100644 --- a/thirdparty/notifier/notifier.go +++ b/thirdparty/notifier/notifier.go @@ -71,7 +71,7 @@ func (n *Notifier) Notify(e Notifiee) { n.mu.Unlock() } -// StopNotifying stops notifying Notifiee e. This function +// StopNotify stops notifying Notifiee e. This function // is meant to be called behind your own type-safe function(s): // // // generic function for pattern-following diff --git a/thirdparty/redis-datastore/datastore.go b/thirdparty/redis-datastore/datastore.go index 139ed86eb..cc3161818 100644 --- a/thirdparty/redis-datastore/datastore.go +++ b/thirdparty/redis-datastore/datastore.go @@ -11,31 +11,31 @@ import ( query "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-datastore/query" ) -var _ datastore.Datastore = &RedisDatastore{} -var _ datastore.ThreadSafeDatastore = &RedisDatastore{} +var _ datastore.Datastore = &Datastore{} +var _ datastore.ThreadSafeDatastore = &Datastore{} var ErrInvalidType = errors.New("redis datastore: invalid type error. this datastore only supports []byte values") func NewExpiringDatastore(client *redis.Client, ttl time.Duration) (datastore.ThreadSafeDatastore, error) { - return &RedisDatastore{ + return &Datastore{ client: client, ttl: ttl, }, nil } func NewDatastore(client *redis.Client) (datastore.ThreadSafeDatastore, error) { - return &RedisDatastore{ + return &Datastore{ client: client, }, nil } -type RedisDatastore struct { +type Datastore struct { mu sync.Mutex client *redis.Client ttl time.Duration } -func (ds *RedisDatastore) Put(key datastore.Key, value interface{}) error { +func (ds *Datastore) Put(key datastore.Key, value interface{}) error { ds.mu.Lock() defer ds.mu.Unlock() @@ -59,26 +59,26 @@ func (ds *RedisDatastore) Put(key datastore.Key, value interface{}) error { return nil } -func (ds *RedisDatastore) Get(key datastore.Key) (value interface{}, err error) { +func (ds *Datastore) Get(key datastore.Key) (value interface{}, err error) { ds.mu.Lock() defer ds.mu.Unlock() return ds.client.Cmd("GET", key.String()).Bytes() } -func (ds *RedisDatastore) Has(key datastore.Key) (exists bool, err error) { +func (ds *Datastore) Has(key datastore.Key) (exists bool, err error) { ds.mu.Lock() defer ds.mu.Unlock() return ds.client.Cmd("EXISTS", key.String()).Bool() } -func (ds *RedisDatastore) Delete(key datastore.Key) (err error) { +func (ds *Datastore) Delete(key datastore.Key) (err error) { ds.mu.Lock() defer ds.mu.Unlock() return ds.client.Cmd("DEL", key.String()).Err } -func (ds *RedisDatastore) Query(q query.Query) (query.Results, error) { +func (ds *Datastore) Query(q query.Query) (query.Results, error) { return nil, errors.New("TODO implement query for redis datastore?") } -func (ds *RedisDatastore) IsThreadSafe() {} +func (ds *Datastore) IsThreadSafe() {} diff --git a/thirdparty/unit/unit.go b/thirdparty/unit/unit.go index 866beea51..feeaa42bb 100644 --- a/thirdparty/unit/unit.go +++ b/thirdparty/unit/unit.go @@ -19,7 +19,7 @@ func (i Information) String() string { tmp := int64(i) // default - var d int64 = tmp + var d = tmp symbol := "B" switch { diff --git a/updates/updates.go b/updates/updates.go index d2bdd3dcb..9a87375bb 100644 --- a/updates/updates.go +++ b/updates/updates.go @@ -90,8 +90,7 @@ func init() { var err error currentVersion, err = parseVersion() if err != nil { - log.Criticalf("invalid version number in code (must be semver): %q", Version) - os.Exit(1) + log.Fatalf("invalid version number in code (must be semver): %q", Version) } log.Infof("go-ipfs Version: %s", currentVersion) } @@ -211,7 +210,7 @@ func CliCheckForUpdates(cfg *config.Config, repoPath string) error { // if there is no update available, record it, and exit. NB: only record // if we checked successfully. if err == ErrNoUpdateAvailable { - log.Noticef("No update available, checked on %s", time.Now()) + log.Infof("No update available, checked on %s", time.Now()) r, err := fsrepo.Open(repoPath) if err != nil { return err @@ -239,7 +238,7 @@ func CliCheckForUpdates(cfg *config.Config, repoPath string) error { if cfg.Version.AutoUpdate != config.AutoUpdateNever { // and we should auto update if ShouldAutoUpdate(cfg.Version.AutoUpdate, u.Version) { - log.Noticef("Applying update %s", u.Version) + log.Infof("Applying update %s", u.Version) if err = Apply(u); err != nil { log.Debug(err) diff --git a/util/log.go b/util/log.go index 541991755..b6c695dda 100644 --- a/util/log.go +++ b/util/log.go @@ -3,23 +3,21 @@ package util import ( "os" - logging "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/whyrusleeping/go-logging" + "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/Sirupsen/logrus" ) func init() { SetupLogging() } -var log = Logger("util") - -var ansiGray = "\033[0;37m" -var ansiBlue = "\033[0;34m" +var log = logrus.New() // LogFormats is a map of formats used for our logger, keyed by name. -var LogFormats = map[string]string{ - "nocolor": "%{time:2006-01-02 15:04:05.000000} %{level} %{module} %{shortfile}: %{message}", - "color": ansiGray + "%{time:15:04:05.000} %{color}%{level:5.5s} " + ansiBlue + - "%{module:10.10s}: %{color:reset}%{message} " + ansiGray + "%{shortfile}%{color:reset}", +// TODO: write custom TextFormatter (don't print module=name explicitly) and +// fork logrus to add shortfile +var LogFormats = map[string]*logrus.TextFormatter{ + "nocolor": &logrus.TextFormatter{DisableColors: true, FullTimestamp: true, TimestampFormat: "2006-01-02 15:04:05.000000", DisableSorting: true}, + "color": &logrus.TextFormatter{DisableColors: false, FullTimestamp: true, TimestampFormat: "15:04:05:000", DisableSorting: true}, } var defaultLogFormat = "color" @@ -30,65 +28,66 @@ const ( ) // loggers is the set of loggers in the system -var loggers = map[string]*logging.Logger{} +var loggers = map[string]*logrus.Entry{} // SetupLogging will initialize the logger backend and set the flags. func SetupLogging() { - fmt := LogFormats[os.Getenv(envLoggingFmt)] - if fmt == "" { - fmt = LogFormats[defaultLogFormat] + format, ok := LogFormats[os.Getenv(envLoggingFmt)] + if !ok { + format = LogFormats[defaultLogFormat] } - backend := logging.NewLogBackend(os.Stderr, "", 0) - logging.SetBackend(backend) - logging.SetFormatter(logging.MustStringFormatter(fmt)) + log.Out = os.Stderr + log.Formatter = format - lvl := logging.ERROR + lvl := logrus.ErrorLevel if logenv := os.Getenv(envLogging); logenv != "" { var err error - lvl, err = logging.LogLevel(logenv) + lvl, err = logrus.ParseLevel(logenv) if err != nil { - log.Debugf("logging.LogLevel() Error: %q", err) - lvl = logging.ERROR // reset to ERROR, could be undefined now(?) + log.Debugf("logrus.ParseLevel() Error: %q", err) + lvl = logrus.ErrorLevel // reset to ERROR, could be undefined now(?) } } - Debug = GetenvBool("IPFS_DEBUG") - if Debug { - lvl = logging.DEBUG + if Debug := GetenvBool("IPFS_DEBUG"); Debug { + lvl = logrus.DebugLevel } SetAllLoggers(lvl) - } -// SetDebugLogging calls SetAllLoggers with logging.DEBUG +// SetDebugLogging calls SetAllLoggers with logrus.DebugLevel func SetDebugLogging() { - SetAllLoggers(logging.DEBUG) + SetAllLoggers(logrus.DebugLevel) } -// SetAllLoggers changes the logging.Level of all loggers to lvl -func SetAllLoggers(lvl logging.Level) { - logging.SetLevel(lvl, "") - for n := range loggers { - logging.SetLevel(lvl, n) +// SetAllLoggers changes the logrus.Level of all loggers to lvl +func SetAllLoggers(lvl logrus.Level) { + log.Level = lvl + for _, logger := range loggers { + logger.Level = lvl } } // Logger retrieves a particular logger -func Logger(name string) *logging.Logger { - log := logging.MustGetLogger(name) - log.ExtraCalldepth = 1 - loggers[name] = log - return log +func Logger(name string) *logrus.Entry { + if len(name) == 0 { + log.Warnf("Missing name parameter") + name = "undefined" + } + if _, ok := loggers[name]; !ok { + loggers[name] = log.WithField("module", name) + } + return loggers[name] } // SetLogLevel changes the log level of a specific subsystem // name=="*" changes all subsystems func SetLogLevel(name, level string) error { - lvl, err := logging.LogLevel(level) + lvl, err := logrus.ParseLevel(level) if err != nil { return err } @@ -100,13 +99,11 @@ func SetLogLevel(name, level string) error { } // Check if we have a logger by that name - // logging.SetLevel() can't tell us... - _, ok := loggers[name] - if !ok { + if _, ok := loggers[name]; !ok { return ErrNoSuchLogger } - logging.SetLevel(lvl, name) + loggers[name].Level = lvl return nil } diff --git a/util/prefixlog/prefixlog.go b/util/prefixlog/prefixlog.go deleted file mode 100644 index c0d62a99f..000000000 --- a/util/prefixlog/prefixlog.go +++ /dev/null @@ -1,151 +0,0 @@ -package eventlog - -import ( - "strings" - - "github.com/ipfs/go-ipfs/util" -) - -// StandardLogger provides API compatibility with standard printf loggers -// eg. go-logging -type StandardLogger interface { - Critical(args ...interface{}) - Criticalf(format string, args ...interface{}) - Debug(args ...interface{}) - Debugf(format string, args ...interface{}) - Error(args ...interface{}) - Errorf(format string, args ...interface{}) - Fatal(args ...interface{}) - Fatalf(format string, args ...interface{}) - Info(args ...interface{}) - Infof(format string, args ...interface{}) - Notice(args ...interface{}) - Noticef(format string, args ...interface{}) - Panic(args ...interface{}) - Panicf(format string, args ...interface{}) - Warning(args ...interface{}) - Warningf(format string, args ...interface{}) -} - -// StandardLogger provides API compatibility with standard printf loggers -// eg. go-logging -type PrefixLogger interface { - StandardLogger - - Format() string - Args() []interface{} - - Prefix(fmt string, args ...interface{}) PrefixLogger -} - -// Logger retrieves an event logger by name -func Logger(system string) PrefixLogger { - - // TODO if we would like to adjust log levels at run-time. Store this event - // logger in a map (just like the util.Logger impl) - - logger := util.Logger(system) - return Prefix(logger, "") -} - -func Prefix(l StandardLogger, format string, args ...interface{}) PrefixLogger { - return &prefixLogger{logger: l, format: format, args: args} -} - -type prefixLogger struct { - logger StandardLogger - format string - args []interface{} -} - -func (pl *prefixLogger) Format() string { - return pl.format -} - -func (pl *prefixLogger) Args() []interface{} { - return pl.args -} - -func (pl *prefixLogger) Prefix(fmt string, args ...interface{}) PrefixLogger { - return Prefix(pl, fmt, args...) -} - -func (pl *prefixLogger) prepend(fmt string, args []interface{}) (string, []interface{}) { - together := make([]interface{}, 0, len(pl.args)+len(args)) - together = append(together, pl.args...) - together = append(together, args...) - if len(pl.format) > 0 { - fmt = pl.format + " " + fmt - } - return fmt, together -} - -func valfmtn(count int) string { - s := strings.Repeat("%v ", count) - s = s[:len(s)-1] // remove last space - return s -} - -type logFunc func(args ...interface{}) -type logFuncf func(fmt string, args ...interface{}) - -func (pl *prefixLogger) logFunc(f logFuncf, args ...interface{}) { - // need to actually use the format version, with extra fmt strings appended - fmt := valfmtn(len(args)) - pl.logFuncf(f, fmt, args...) -} - -func (pl *prefixLogger) logFuncf(f logFuncf, format string, args ...interface{}) { - format, args = pl.prepend(format, args) - f(format, args...) -} - -func (pl *prefixLogger) Critical(args ...interface{}) { - pl.logFunc(pl.logger.Criticalf, args...) -} -func (pl *prefixLogger) Debug(args ...interface{}) { - pl.logFunc(pl.logger.Debugf, args...) -} -func (pl *prefixLogger) Error(args ...interface{}) { - pl.logFunc(pl.logger.Errorf, args...) -} -func (pl *prefixLogger) Fatal(args ...interface{}) { - pl.logFunc(pl.logger.Fatalf, args...) -} -func (pl *prefixLogger) Info(args ...interface{}) { - pl.logFunc(pl.logger.Infof, args...) -} -func (pl *prefixLogger) Notice(args ...interface{}) { - pl.logFunc(pl.logger.Noticef, args...) -} -func (pl *prefixLogger) Panic(args ...interface{}) { - pl.logFunc(pl.logger.Panicf, args...) -} -func (pl *prefixLogger) Warning(args ...interface{}) { - pl.logFunc(pl.logger.Warningf, args...) -} - -func (pl *prefixLogger) Criticalf(format string, args ...interface{}) { - pl.logFuncf(pl.logger.Criticalf, format, args...) -} -func (pl *prefixLogger) Debugf(format string, args ...interface{}) { - pl.logFuncf(pl.logger.Debugf, format, args...) -} -func (pl *prefixLogger) Errorf(format string, args ...interface{}) { - pl.logFuncf(pl.logger.Errorf, format, args...) -} -func (pl *prefixLogger) Fatalf(format string, args ...interface{}) { - pl.logFuncf(pl.logger.Fatalf, format, args...) -} -func (pl *prefixLogger) Infof(format string, args ...interface{}) { - pl.logFuncf(pl.logger.Infof, format, args...) -} -func (pl *prefixLogger) Noticef(format string, args ...interface{}) { - pl.logFuncf(pl.logger.Noticef, format, args...) -} -func (pl *prefixLogger) Panicf(format string, args ...interface{}) { - pl.logFuncf(pl.logger.Panicf, format, args...) -} -func (pl *prefixLogger) Warningf(format string, args ...interface{}) { - pl.logFuncf(pl.logger.Warningf, format, args...) -} diff --git a/util/testutil/gen.go b/util/testutil/gen.go index bfc73723a..1d5d359d3 100644 --- a/util/testutil/gen.go +++ b/util/testutil/gen.go @@ -122,7 +122,7 @@ func (p *PeerNetParams) checkKeys() error { return fmt.Errorf("sig verify failed: %s", err) } if !sigok { - return fmt.Errorf("sig verify failed: sig invalid!") + return fmt.Errorf("sig verify failed: sig invalid") } return nil // ok. move along. diff --git a/util/testutil/latency_config.go b/util/testutil/latency_config.go index 767b9a638..5628d9ed1 100644 --- a/util/testutil/latency_config.go +++ b/util/testutil/latency_config.go @@ -8,7 +8,7 @@ type LatencyConfig struct { RoutingLatency time.Duration } -func (c LatencyConfig) All_Instantaneous() LatencyConfig { +func (c LatencyConfig) AllInstantaneous() LatencyConfig { // Could use a zero value but whatever. Consistency of interface c.NetworkLatency = 0 c.RoutingLatency = 0 @@ -16,33 +16,33 @@ func (c LatencyConfig) All_Instantaneous() LatencyConfig { return c } -func (c LatencyConfig) Network_NYtoSF() LatencyConfig { +func (c LatencyConfig) NetworkNYtoSF() LatencyConfig { c.NetworkLatency = 20 * time.Millisecond return c } -func (c LatencyConfig) Network_IntraDatacenter2014() LatencyConfig { +func (c LatencyConfig) NetworkIntraDatacenter2014() LatencyConfig { c.NetworkLatency = 250 * time.Microsecond return c } -func (c LatencyConfig) Blockstore_FastSSD2014() LatencyConfig { +func (c LatencyConfig) BlockstoreFastSSD2014() LatencyConfig { const iops = 100000 c.BlockstoreLatency = (1 / iops) * time.Second return c } -func (c LatencyConfig) Blockstore_SlowSSD2014() LatencyConfig { +func (c LatencyConfig) BlockstoreSlowSSD2014() LatencyConfig { c.BlockstoreLatency = 150 * time.Microsecond return c } -func (c LatencyConfig) Blockstore_7200RPM() LatencyConfig { +func (c LatencyConfig) Blockstore7200RPM() LatencyConfig { c.BlockstoreLatency = 8 * time.Millisecond return c } -func (c LatencyConfig) Routing_Slow() LatencyConfig { +func (c LatencyConfig) RoutingSlow() LatencyConfig { c.RoutingLatency = 200 * time.Millisecond return c } diff --git a/util/util.go b/util/util.go index 8823a6bf3..d0fee9d42 100644 --- a/util/util.go +++ b/util/util.go @@ -1,4 +1,4 @@ -// package util implements various utility functions used within ipfs +// Package util implements various utility functions used within ipfs // that do not currently have a better place to live. package util @@ -95,7 +95,7 @@ func GetenvBool(name string) bool { return v == "true" || v == "t" || v == "1" } -// multiErr is a util to return multiple errors +// MultiErr is a util to return multiple errors type MultiErr []error func (m MultiErr) Error() string { @@ -116,17 +116,15 @@ func (m MultiErr) Error() string { func Partition(subject string, sep string) (string, string, string) { if i := strings.Index(subject, sep); i != -1 { return subject[:i], subject[i : i+len(sep)], subject[i+len(sep):] - } else { - return subject, "", "" } + return subject, "", "" } func RPartition(subject string, sep string) (string, string, string) { if i := strings.LastIndex(subject, sep); i != -1 { return subject[:i], subject[i : i+len(sep)], subject[i+len(sep):] - } else { - return subject, "", "" } + return subject, "", "" } // Hash is the global IPFS hash function. uses multihash SHA2_256, 256 bits