Update vendoring, update .gitignore
This commit is contained in:
parent
f129a30515
commit
34527f510e
|
@ -1,4 +1,3 @@
|
|||
.build
|
||||
data
|
||||
alertmanager
|
||||
*.yml
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
package manager
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/prometheus/common/mode"
|
||||
)
|
||||
|
||||
func TestAggrGroupInsert(t *testing.T) {
|
||||
ag := newAggrGroup(nil, model.LabelSet{
|
||||
model.AlertNameLabel: "test",
|
||||
}, opts)
|
||||
}
|
146
vendor.json
146
vendor.json
|
@ -1,146 +0,0 @@
|
|||
{
|
||||
"comment": "",
|
||||
"ignore": "test",
|
||||
"package": [
|
||||
{
|
||||
"canonical": "github.com/Sirupsen/logrus",
|
||||
"comment": "",
|
||||
"local": "vendor/github.com/Sirupsen/logrus",
|
||||
"revision": "0f2a4955b11372eec5a4b95d907eaf8379b835d0",
|
||||
"revisionTime": "2015-06-02T19:14:05-04:00"
|
||||
},
|
||||
{
|
||||
"canonical": "github.com/julienschmidt/httprouter",
|
||||
"comment": "",
|
||||
"local": "vendor/github.com/julienschmidt/httprouter",
|
||||
"revision": "8c199fb6259ffc1af525cc3ad52ee60ba8359669",
|
||||
"revisionTime": "2015-04-21T19:00:07+02:00"
|
||||
},
|
||||
{
|
||||
"canonical": "github.com/prometheus/common/model",
|
||||
"comment": "",
|
||||
"local": "vendor/github.com/prometheus/common/model",
|
||||
"revision": "c33395bbc758c8d25735ec7036d66b342084ae35",
|
||||
"revisionTime": "2015-08-25T14:37:19+02:00"
|
||||
},
|
||||
{
|
||||
"canonical": "github.com/prometheus/common/route",
|
||||
"comment": "",
|
||||
"local": "vendor/github.com/prometheus/common/route",
|
||||
"revision": "c33395bbc758c8d25735ec7036d66b342084ae35",
|
||||
"revisionTime": "2015-08-25T14:37:19+02:00"
|
||||
},
|
||||
{
|
||||
"canonical": "github.com/prometheus/log",
|
||||
"comment": "",
|
||||
"local": "vendor/github.com/prometheus/log",
|
||||
"revision": "439e5db48fbb50ebbaf2c816030473a62f505f55",
|
||||
"revisionTime": "2015-05-29T14:22:02+02:00"
|
||||
},
|
||||
{
|
||||
"canonical": "github.com/syndtr/goleveldb/leveldb",
|
||||
"comment": "",
|
||||
"local": "vendor/github.com/syndtr/goleveldb/leveldb",
|
||||
"revision": "315fcfb05d4d46d4354b313d146ef688dda272a9",
|
||||
"revisionTime": "2015-05-13T20:13:07+07:00"
|
||||
},
|
||||
{
|
||||
"canonical": "github.com/syndtr/goleveldb/leveldb/cache",
|
||||
"comment": "",
|
||||
"local": "vendor/github.com/syndtr/goleveldb/leveldb/cache",
|
||||
"revision": "315fcfb05d4d46d4354b313d146ef688dda272a9",
|
||||
"revisionTime": "2015-05-13T20:13:07+07:00"
|
||||
},
|
||||
{
|
||||
"canonical": "github.com/syndtr/goleveldb/leveldb/comparer",
|
||||
"comment": "",
|
||||
"local": "vendor/github.com/syndtr/goleveldb/leveldb/comparer",
|
||||
"revision": "315fcfb05d4d46d4354b313d146ef688dda272a9",
|
||||
"revisionTime": "2015-05-13T20:13:07+07:00"
|
||||
},
|
||||
{
|
||||
"canonical": "github.com/syndtr/goleveldb/leveldb/errors",
|
||||
"comment": "",
|
||||
"local": "vendor/github.com/syndtr/goleveldb/leveldb/errors",
|
||||
"revision": "315fcfb05d4d46d4354b313d146ef688dda272a9",
|
||||
"revisionTime": "2015-05-13T20:13:07+07:00"
|
||||
},
|
||||
{
|
||||
"canonical": "github.com/syndtr/goleveldb/leveldb/filter",
|
||||
"comment": "",
|
||||
"local": "vendor/github.com/syndtr/goleveldb/leveldb/filter",
|
||||
"revision": "315fcfb05d4d46d4354b313d146ef688dda272a9",
|
||||
"revisionTime": "2015-05-13T20:13:07+07:00"
|
||||
},
|
||||
{
|
||||
"canonical": "github.com/syndtr/goleveldb/leveldb/iterator",
|
||||
"comment": "",
|
||||
"local": "vendor/github.com/syndtr/goleveldb/leveldb/iterator",
|
||||
"revision": "315fcfb05d4d46d4354b313d146ef688dda272a9",
|
||||
"revisionTime": "2015-05-13T20:13:07+07:00"
|
||||
},
|
||||
{
|
||||
"canonical": "github.com/syndtr/goleveldb/leveldb/journal",
|
||||
"comment": "",
|
||||
"local": "vendor/github.com/syndtr/goleveldb/leveldb/journal",
|
||||
"revision": "315fcfb05d4d46d4354b313d146ef688dda272a9",
|
||||
"revisionTime": "2015-05-13T20:13:07+07:00"
|
||||
},
|
||||
{
|
||||
"canonical": "github.com/syndtr/goleveldb/leveldb/memdb",
|
||||
"comment": "",
|
||||
"local": "vendor/github.com/syndtr/goleveldb/leveldb/memdb",
|
||||
"revision": "315fcfb05d4d46d4354b313d146ef688dda272a9",
|
||||
"revisionTime": "2015-05-13T20:13:07+07:00"
|
||||
},
|
||||
{
|
||||
"canonical": "github.com/syndtr/goleveldb/leveldb/opt",
|
||||
"comment": "",
|
||||
"local": "vendor/github.com/syndtr/goleveldb/leveldb/opt",
|
||||
"revision": "315fcfb05d4d46d4354b313d146ef688dda272a9",
|
||||
"revisionTime": "2015-05-13T20:13:07+07:00"
|
||||
},
|
||||
{
|
||||
"canonical": "github.com/syndtr/goleveldb/leveldb/storage",
|
||||
"comment": "",
|
||||
"local": "vendor/github.com/syndtr/goleveldb/leveldb/storage",
|
||||
"revision": "315fcfb05d4d46d4354b313d146ef688dda272a9",
|
||||
"revisionTime": "2015-05-13T20:13:07+07:00"
|
||||
},
|
||||
{
|
||||
"canonical": "github.com/syndtr/goleveldb/leveldb/table",
|
||||
"comment": "",
|
||||
"local": "vendor/github.com/syndtr/goleveldb/leveldb/table",
|
||||
"revision": "315fcfb05d4d46d4354b313d146ef688dda272a9",
|
||||
"revisionTime": "2015-05-13T20:13:07+07:00"
|
||||
},
|
||||
{
|
||||
"canonical": "github.com/syndtr/goleveldb/leveldb/util",
|
||||
"comment": "",
|
||||
"local": "vendor/github.com/syndtr/goleveldb/leveldb/util",
|
||||
"revision": "315fcfb05d4d46d4354b313d146ef688dda272a9",
|
||||
"revisionTime": "2015-05-13T20:13:07+07:00"
|
||||
},
|
||||
{
|
||||
"canonical": "github.com/syndtr/gosnappy/snappy",
|
||||
"comment": "",
|
||||
"local": "vendor/github.com/syndtr/gosnappy/snappy",
|
||||
"revision": "156a073208e131d7d2e212cb749feae7c339e846",
|
||||
"revisionTime": "2015-02-10T15:23:34+11:00"
|
||||
},
|
||||
{
|
||||
"canonical": "golang.org/x/net/context",
|
||||
"comment": "",
|
||||
"local": "vendor/golang.org/x/net/context",
|
||||
"revision": "ad9eb3904af97b912b9a242efb203c5c6782e72a",
|
||||
"revisionTime": "2015-05-21T17:33:58+10:00"
|
||||
},
|
||||
{
|
||||
"canonical": "gopkg.in/yaml.v2",
|
||||
"comment": "",
|
||||
"local": "vendor/gopkg.in/yaml.v2",
|
||||
"revision": "49c95bdc21843256fb6c4e0d370a05f24a0bf213",
|
||||
"revisionTime": "2015-02-24T19:57:58-03:00"
|
||||
}
|
||||
]
|
||||
}
|
|
@ -1,21 +1,47 @@
|
|||
# 0.8.7
|
||||
|
||||
* logrus/core: fix possible race (#216)
|
||||
* logrus/doc: small typo fixes and doc improvements
|
||||
|
||||
|
||||
# 0.8.6
|
||||
|
||||
* hooks/raven: allow passing an initialized client
|
||||
|
||||
# 0.8.5
|
||||
|
||||
* logrus/core: revert #208
|
||||
|
||||
# 0.8.4
|
||||
|
||||
* formatter/text: fix data race (#218)
|
||||
|
||||
# 0.8.3
|
||||
|
||||
* logrus/core: fix entry log level (#208)
|
||||
* logrus/core: improve performance of text formatter by 40%
|
||||
* logrus/core: expose `LevelHooks` type
|
||||
* logrus/core: add support for DragonflyBSD and NetBSD
|
||||
* formatter/text: print structs more verbosely
|
||||
|
||||
# 0.8.2
|
||||
|
||||
logrus: fix more Fatal family functions
|
||||
* logrus: fix more Fatal family functions
|
||||
|
||||
# 0.8.1
|
||||
|
||||
logrus: fix not exiting on `Fatalf` and `Fatalln`
|
||||
* logrus: fix not exiting on `Fatalf` and `Fatalln`
|
||||
|
||||
# 0.8.0
|
||||
|
||||
logrus: defaults to stderr instead of stdout
|
||||
hooks/sentry: add special field for `*http.Request`
|
||||
formatter/text: ignore Windows for colors
|
||||
* logrus: defaults to stderr instead of stdout
|
||||
* hooks/sentry: add special field for `*http.Request`
|
||||
* formatter/text: ignore Windows for colors
|
||||
|
||||
# 0.7.3
|
||||
|
||||
formatter/\*: allow configuration of timestamp layout
|
||||
* formatter/\*: allow configuration of timestamp layout
|
||||
|
||||
# 0.7.2
|
||||
|
||||
formatter/text: Add configuration option for time format (#158)
|
||||
* formatter/text: Add configuration option for time format (#158)
|
||||
|
|
|
@ -206,6 +206,7 @@ func init() {
|
|||
| [Papertrail](https://github.com/Sirupsen/logrus/blob/master/hooks/papertrail/papertrail.go) | Send errors to the Papertrail hosted logging service via UDP. |
|
||||
| [Syslog](https://github.com/Sirupsen/logrus/blob/master/hooks/syslog/syslog.go) | Send errors to remote syslog server. Uses standard library `log/syslog` behind the scenes. |
|
||||
| [BugSnag](https://github.com/Sirupsen/logrus/blob/master/hooks/bugsnag/bugsnag.go) | Send errors to the Bugsnag exception tracking service. |
|
||||
| [Sentry](https://github.com/Sirupsen/logrus/blob/master/hooks/sentry/sentry.go) | Send errors to the Sentry error logging and aggregation service. |
|
||||
| [Hiprus](https://github.com/nubo/hiprus) | Send errors to a channel in hipchat. |
|
||||
| [Logrusly](https://github.com/sebest/logrusly) | Send logs to [Loggly](https://www.loggly.com/) |
|
||||
| [Slackrus](https://github.com/johntdyer/slackrus) | Hook for Slack chat. |
|
||||
|
@ -213,6 +214,11 @@ func init() {
|
|||
| [Graylog](https://github.com/gemnasium/logrus-hooks/tree/master/graylog) | Hook for logging to [Graylog](http://graylog2.org/) |
|
||||
| [Raygun](https://github.com/squirkle/logrus-raygun-hook) | Hook for logging to [Raygun.io](http://raygun.io/) |
|
||||
| [LFShook](https://github.com/rifflock/lfshook) | Hook for logging to the local filesystem |
|
||||
| [Honeybadger](https://github.com/agonzalezro/logrus_honeybadger) | Hook for sending exceptions to Honeybadger |
|
||||
| [Mail](https://github.com/zbindenren/logrus_mail) | Hook for sending exceptions via mail |
|
||||
| [Rollrus](https://github.com/heroku/rollrus) | Hook for sending errors to rollbar |
|
||||
| [Fluentd](https://github.com/evalphobia/logrus_fluent) | Hook for logging to fluentd |
|
||||
| [Mongodb](https://github.com/weekface/mgorus) | Hook for logging to mongodb |
|
||||
|
||||
#### Level logging
|
||||
|
||||
|
@ -268,7 +274,7 @@ init() {
|
|||
// do something here to set environment depending on an environment variable
|
||||
// or command-line flag
|
||||
if Environment == "production" {
|
||||
log.SetFormatter(&logrus.JSONFormatter{})
|
||||
log.SetFormatter(&log.JSONFormatter{})
|
||||
} else {
|
||||
// The TextFormatter is default, you don't actually have to do this.
|
||||
log.SetFormatter(&log.TextFormatter{})
|
||||
|
@ -311,7 +317,7 @@ type MyJSONFormatter struct {
|
|||
|
||||
log.SetFormatter(new(MyJSONFormatter))
|
||||
|
||||
func (f *JSONFormatter) Format(entry *Entry) ([]byte, error) {
|
||||
func (f *MyJSONFormatter) Format(entry *Entry) ([]byte, error) {
|
||||
// Note this doesn't include Time, Level and Message which are available on
|
||||
// the Entry. Consult `godoc` on information about those fields or read the
|
||||
// source of the official loggers.
|
||||
|
@ -325,7 +331,7 @@ func (f *JSONFormatter) Format(entry *Entry) ([]byte, error) {
|
|||
|
||||
#### Logger as an `io.Writer`
|
||||
|
||||
Logrus can be transormed into an `io.Writer`. That writer is the end of an `io.Pipe` and it is your responsibility to close it.
|
||||
Logrus can be transformed into an `io.Writer`. That writer is the end of an `io.Pipe` and it is your responsibility to close it.
|
||||
|
||||
```go
|
||||
w := logger.Writer()
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
Package logrus is a structured logger for Go, completely API compatible with the standard library logger.
|
||||
|
||||
|
||||
The simplest way to use Logrus is simply the package-level exported logger:
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
log "github.com/Sirupsen/logrus"
|
||||
)
|
||||
|
||||
func main() {
|
||||
log.WithFields(log.Fields{
|
||||
"animal": "walrus",
|
||||
"number": 1,
|
||||
"size": 10,
|
||||
}).Info("A walrus appears")
|
||||
}
|
||||
|
||||
Output:
|
||||
time="2015-09-07T08:48:33Z" level=info msg="A walrus appears" animal=walrus number=1 size=10
|
||||
|
||||
For a full guide visit https://github.com/Sirupsen/logrus
|
||||
*/
|
||||
package logrus
|
|
@ -8,6 +8,9 @@ import (
|
|||
"time"
|
||||
)
|
||||
|
||||
// Defines the key when adding errors using WithError.
|
||||
var ErrorKey = "error"
|
||||
|
||||
// An entry is the final or intermediate Logrus logging entry. It contains all
|
||||
// the fields passed with WithField{,s}. It's finally logged when Debug, Info,
|
||||
// Warn, Error, Fatal or Panic is called on it. These objects can be reused and
|
||||
|
@ -53,6 +56,11 @@ func (entry *Entry) String() (string, error) {
|
|||
return reader.String(), err
|
||||
}
|
||||
|
||||
// Add an error as single field (using the key defined in ErrorKey) to the Entry.
|
||||
func (entry *Entry) WithError(err error) *Entry {
|
||||
return entry.WithField(ErrorKey, err)
|
||||
}
|
||||
|
||||
// Add a single field to the Entry.
|
||||
func (entry *Entry) WithField(key string, value interface{}) *Entry {
|
||||
return entry.WithFields(Fields{key: value})
|
||||
|
@ -70,12 +78,14 @@ func (entry *Entry) WithFields(fields Fields) *Entry {
|
|||
return &Entry{Logger: entry.Logger, Data: data}
|
||||
}
|
||||
|
||||
func (entry *Entry) log(level Level, msg string) {
|
||||
// This function is not declared with a pointer value because otherwise
|
||||
// race conditions will occur when using multiple goroutines
|
||||
func (entry Entry) log(level Level, msg string) {
|
||||
entry.Time = time.Now()
|
||||
entry.Level = level
|
||||
entry.Message = msg
|
||||
|
||||
if err := entry.Logger.Hooks.Fire(level, entry); err != nil {
|
||||
if err := entry.Logger.Hooks.Fire(level, &entry); err != nil {
|
||||
entry.Logger.mu.Lock()
|
||||
fmt.Fprintf(os.Stderr, "Failed to fire hook: %v\n", err)
|
||||
entry.Logger.mu.Unlock()
|
||||
|
@ -100,7 +110,7 @@ func (entry *Entry) log(level Level, msg string) {
|
|||
// panic() to use in Entry#Panic(), we avoid the allocation by checking
|
||||
// directly here.
|
||||
if level <= PanicLevel {
|
||||
panic(entry)
|
||||
panic(&entry)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -48,6 +48,11 @@ func AddHook(hook Hook) {
|
|||
std.Hooks.Add(hook)
|
||||
}
|
||||
|
||||
// WithError creates an entry from the standard logger and adds an error to it, using the value defined in ErrorKey as key.
|
||||
func WithError(err error) *Entry {
|
||||
return std.WithField(ErrorKey, err)
|
||||
}
|
||||
|
||||
// WithField creates an entry from the standard logger and adds a field to
|
||||
// it. If you want multiple fields, use `WithFields`.
|
||||
//
|
||||
|
|
|
@ -11,11 +11,11 @@ type Hook interface {
|
|||
}
|
||||
|
||||
// Internal type for storing the hooks on a logger instance.
|
||||
type levelHooks map[Level][]Hook
|
||||
type LevelHooks map[Level][]Hook
|
||||
|
||||
// Add a hook to an instance of logger. This is called with
|
||||
// `log.Hooks.Add(new(MyHook))` where `MyHook` implements the `Hook` interface.
|
||||
func (hooks levelHooks) Add(hook Hook) {
|
||||
func (hooks LevelHooks) Add(hook Hook) {
|
||||
for _, level := range hook.Levels() {
|
||||
hooks[level] = append(hooks[level], hook)
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ func (hooks levelHooks) Add(hook Hook) {
|
|||
|
||||
// Fire all the hooks for the passed level. Used by `entry.log` to fire
|
||||
// appropriate hooks for a log entry.
|
||||
func (hooks levelHooks) Fire(level Level, entry *Entry) error {
|
||||
func (hooks LevelHooks) Fire(level Level, entry *Entry) error {
|
||||
for _, hook := range hooks[level] {
|
||||
if err := hook.Fire(entry); err != nil {
|
||||
return err
|
||||
|
|
|
@ -8,13 +8,13 @@ import (
|
|||
|
||||
type Logger struct {
|
||||
// The logs are `io.Copy`'d to this in a mutex. It's common to set this to a
|
||||
// file, or leave it default which is `os.Stdout`. You can also set this to
|
||||
// file, or leave it default which is `os.Stderr`. You can also set this to
|
||||
// something more adventorous, such as logging to Kafka.
|
||||
Out io.Writer
|
||||
// Hooks for the logger instance. These allow firing events based on logging
|
||||
// levels and log entries. For example, to send errors to an error tracking
|
||||
// service, log to StatsD or dump the core on fatal errors.
|
||||
Hooks levelHooks
|
||||
Hooks LevelHooks
|
||||
// All log entries pass through the formatter before logged to Out. The
|
||||
// included formatters are `TextFormatter` and `JSONFormatter` for which
|
||||
// TextFormatter is the default. In development (when a TTY is attached) it
|
||||
|
@ -37,7 +37,7 @@ type Logger struct {
|
|||
// var log = &Logger{
|
||||
// Out: os.Stderr,
|
||||
// Formatter: new(JSONFormatter),
|
||||
// Hooks: make(levelHooks),
|
||||
// Hooks: make(LevelHooks),
|
||||
// Level: logrus.DebugLevel,
|
||||
// }
|
||||
//
|
||||
|
@ -46,14 +46,14 @@ func New() *Logger {
|
|||
return &Logger{
|
||||
Out: os.Stderr,
|
||||
Formatter: new(TextFormatter),
|
||||
Hooks: make(levelHooks),
|
||||
Hooks: make(LevelHooks),
|
||||
Level: InfoLevel,
|
||||
}
|
||||
}
|
||||
|
||||
// Adds a field to the log entry, note that you it doesn't log until you call
|
||||
// Debug, Print, Info, Warn, Fatal or Panic. It only creates a log entry.
|
||||
// Ff you want multiple fields, use `WithFields`.
|
||||
// If you want multiple fields, use `WithFields`.
|
||||
func (logger *Logger) WithField(key string, value interface{}) *Entry {
|
||||
return NewEntry(logger).WithField(key, value)
|
||||
}
|
||||
|
|
|
@ -74,7 +74,11 @@ const (
|
|||
)
|
||||
|
||||
// Won't compile if StdLogger can't be realized by a log.Logger
|
||||
var _ StdLogger = &log.Logger{}
|
||||
var (
|
||||
_ StdLogger = &log.Logger{}
|
||||
_ StdLogger = &Entry{}
|
||||
_ StdLogger = &Logger{}
|
||||
)
|
||||
|
||||
// StdLogger is what your logrus-enabled library should take, that way
|
||||
// it'll accept a stdlib logger and a logrus logger. There's no standard
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
// +build darwin freebsd openbsd netbsd dragonfly
|
||||
|
||||
package logrus
|
||||
|
||||
import "syscall"
|
|
@ -1,12 +0,0 @@
|
|||
// Based on ssh/terminal:
|
||||
// Copyright 2013 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package logrus
|
||||
|
||||
import "syscall"
|
||||
|
||||
const ioctlReadTermios = syscall.TIOCGETA
|
||||
|
||||
type Termios syscall.Termios
|
|
@ -1,20 +0,0 @@
|
|||
/*
|
||||
Go 1.2 doesn't include Termios for FreeBSD. This should be added in 1.3 and this could be merged with terminal_darwin.
|
||||
*/
|
||||
package logrus
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
)
|
||||
|
||||
const ioctlReadTermios = syscall.TIOCGETA
|
||||
|
||||
type Termios struct {
|
||||
Iflag uint32
|
||||
Oflag uint32
|
||||
Cflag uint32
|
||||
Lflag uint32
|
||||
Cc [20]uint8
|
||||
Ispeed uint32
|
||||
Ospeed uint32
|
||||
}
|
|
@ -3,7 +3,7 @@
|
|||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build linux darwin freebsd openbsd
|
||||
// +build linux darwin freebsd openbsd netbsd dragonfly
|
||||
|
||||
package logrus
|
||||
|
||||
|
|
|
@ -73,14 +73,15 @@ func (f *TextFormatter) Format(entry *Entry) ([]byte, error) {
|
|||
isColorTerminal := isTerminal && (runtime.GOOS != "windows")
|
||||
isColored := (f.ForceColors || isColorTerminal) && !f.DisableColors
|
||||
|
||||
if f.TimestampFormat == "" {
|
||||
f.TimestampFormat = DefaultTimestampFormat
|
||||
timestampFormat := f.TimestampFormat
|
||||
if timestampFormat == "" {
|
||||
timestampFormat = DefaultTimestampFormat
|
||||
}
|
||||
if isColored {
|
||||
f.printColored(b, entry, keys)
|
||||
f.printColored(b, entry, keys, timestampFormat)
|
||||
} else {
|
||||
if !f.DisableTimestamp {
|
||||
f.appendKeyValue(b, "time", entry.Time.Format(f.TimestampFormat))
|
||||
f.appendKeyValue(b, "time", entry.Time.Format(timestampFormat))
|
||||
}
|
||||
f.appendKeyValue(b, "level", entry.Level.String())
|
||||
f.appendKeyValue(b, "msg", entry.Message)
|
||||
|
@ -93,7 +94,7 @@ func (f *TextFormatter) Format(entry *Entry) ([]byte, error) {
|
|||
return b.Bytes(), nil
|
||||
}
|
||||
|
||||
func (f *TextFormatter) printColored(b *bytes.Buffer, entry *Entry, keys []string) {
|
||||
func (f *TextFormatter) printColored(b *bytes.Buffer, entry *Entry, keys []string, timestampFormat string) {
|
||||
var levelColor int
|
||||
switch entry.Level {
|
||||
case DebugLevel:
|
||||
|
@ -111,11 +112,11 @@ func (f *TextFormatter) printColored(b *bytes.Buffer, entry *Entry, keys []strin
|
|||
if !f.FullTimestamp {
|
||||
fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m[%04d] %-44s ", levelColor, levelText, miniTS(), entry.Message)
|
||||
} else {
|
||||
fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m[%s] %-44s ", levelColor, levelText, entry.Time.Format(f.TimestampFormat), entry.Message)
|
||||
fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m[%s] %-44s ", levelColor, levelText, entry.Time.Format(timestampFormat), entry.Message)
|
||||
}
|
||||
for _, k := range keys {
|
||||
v := entry.Data[k]
|
||||
fmt.Fprintf(b, " \x1b[%dm%s\x1b[0m=%v", levelColor, k, v)
|
||||
fmt.Fprintf(b, " \x1b[%dm%s\x1b[0m=%+v", levelColor, k, v)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -131,21 +132,28 @@ func needsQuoting(text string) bool {
|
|||
return true
|
||||
}
|
||||
|
||||
func (f *TextFormatter) appendKeyValue(b *bytes.Buffer, key, value interface{}) {
|
||||
switch value.(type) {
|
||||
func (f *TextFormatter) appendKeyValue(b *bytes.Buffer, key string, value interface{}) {
|
||||
|
||||
b.WriteString(key)
|
||||
b.WriteByte('=')
|
||||
|
||||
switch value := value.(type) {
|
||||
case string:
|
||||
if needsQuoting(value.(string)) {
|
||||
fmt.Fprintf(b, "%v=%s ", key, value)
|
||||
if needsQuoting(value) {
|
||||
b.WriteString(value)
|
||||
} else {
|
||||
fmt.Fprintf(b, "%v=%q ", key, value)
|
||||
fmt.Fprintf(b, "%q", value)
|
||||
}
|
||||
case error:
|
||||
if needsQuoting(value.(error).Error()) {
|
||||
fmt.Fprintf(b, "%v=%s ", key, value)
|
||||
errmsg := value.Error()
|
||||
if needsQuoting(errmsg) {
|
||||
b.WriteString(errmsg)
|
||||
} else {
|
||||
fmt.Fprintf(b, "%v=%q ", key, value)
|
||||
fmt.Fprintf(b, "%q", value)
|
||||
}
|
||||
default:
|
||||
fmt.Fprintf(b, "%v=%v ", key, value)
|
||||
fmt.Fprint(b, value)
|
||||
}
|
||||
|
||||
b.WriteByte(' ')
|
||||
}
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
# This is the official list of Snappy-Go authors for copyright purposes.
|
||||
# This file is distinct from the CONTRIBUTORS files.
|
||||
# See the latter for an explanation.
|
||||
|
||||
# Names should be added to this file as
|
||||
# Name or Organization <email address>
|
||||
# The email address is not required for organizations.
|
||||
|
||||
# Please keep the list sorted.
|
||||
|
||||
Damian Gryski <dgryski@gmail.com>
|
||||
Google Inc.
|
||||
Jan Mercl <0xjnml@gmail.com>
|
||||
Sebastien Binet <seb.binet@gmail.com>
|
|
@ -0,0 +1,36 @@
|
|||
# This is the official list of people who can contribute
|
||||
# (and typically have contributed) code to the Snappy-Go repository.
|
||||
# The AUTHORS file lists the copyright holders; this file
|
||||
# lists people. For example, Google employees are listed here
|
||||
# but not in AUTHORS, because Google holds the copyright.
|
||||
#
|
||||
# The submission process automatically checks to make sure
|
||||
# that people submitting code are listed in this file (by email address).
|
||||
#
|
||||
# Names should be added to this file only after verifying that
|
||||
# the individual or the individual's organization has agreed to
|
||||
# the appropriate Contributor License Agreement, found here:
|
||||
#
|
||||
# http://code.google.com/legal/individual-cla-v1.0.html
|
||||
# http://code.google.com/legal/corporate-cla-v1.0.html
|
||||
#
|
||||
# The agreement for individuals can be filled out on the web.
|
||||
#
|
||||
# When adding J Random Contributor's name to this file,
|
||||
# either J's name or J's organization's name should be
|
||||
# added to the AUTHORS file, depending on whether the
|
||||
# individual or corporate CLA was used.
|
||||
|
||||
# Names should be added to this file like so:
|
||||
# Name <email address>
|
||||
|
||||
# Please keep the list sorted.
|
||||
|
||||
Damian Gryski <dgryski@gmail.com>
|
||||
Jan Mercl <0xjnml@gmail.com>
|
||||
Kai Backman <kaib@golang.org>
|
||||
Marc-Antoine Ruel <maruel@chromium.org>
|
||||
Nigel Tao <nigeltao@golang.org>
|
||||
Rob Pike <r@golang.org>
|
||||
Russ Cox <rsc@golang.org>
|
||||
Sebastien Binet <seb.binet@gmail.com>
|
|
@ -0,0 +1,27 @@
|
|||
Copyright (c) 2011 The Snappy-Go Authors. 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.
|
|
@ -0,0 +1,7 @@
|
|||
The Snappy compression format in the Go programming language.
|
||||
|
||||
To download and install from source:
|
||||
$ go get github.com/golang/snappy
|
||||
|
||||
Unless otherwise noted, the Snappy-Go source files are distributed
|
||||
under the BSD-style license found in the LICENSE file.
|
|
@ -13,6 +13,8 @@ import (
|
|||
var (
|
||||
// ErrCorrupt reports that the input is invalid.
|
||||
ErrCorrupt = errors.New("snappy: corrupt input")
|
||||
// ErrTooLarge reports that the uncompressed length is too large.
|
||||
ErrTooLarge = errors.New("snappy: decoded block is too large")
|
||||
// ErrUnsupported reports that the input isn't supported.
|
||||
ErrUnsupported = errors.New("snappy: unsupported input")
|
||||
)
|
||||
|
@ -27,11 +29,13 @@ func DecodedLen(src []byte) (int, error) {
|
|||
// that the length header occupied.
|
||||
func decodedLen(src []byte) (blockLen, headerLen int, err error) {
|
||||
v, n := binary.Uvarint(src)
|
||||
if n == 0 {
|
||||
if n <= 0 || v > 0xffffffff {
|
||||
return 0, 0, ErrCorrupt
|
||||
}
|
||||
if uint64(int(v)) != v {
|
||||
return 0, 0, errors.New("snappy: decoded block is too large")
|
||||
|
||||
const wordSize = 32 << (^uint(0) >> 32 & 1)
|
||||
if wordSize == 32 && v > 0x7fffffff {
|
||||
return 0, 0, ErrTooLarge
|
||||
}
|
||||
return int(v), n, nil
|
||||
}
|
||||
|
@ -56,7 +60,7 @@ func Decode(dst, src []byte) ([]byte, error) {
|
|||
x := uint(src[s] >> 2)
|
||||
switch {
|
||||
case x < 60:
|
||||
s += 1
|
||||
s++
|
||||
case x == 60:
|
||||
s += 2
|
||||
if s > len(src) {
|
||||
|
@ -130,7 +134,7 @@ func Decode(dst, src []byte) ([]byte, error) {
|
|||
|
||||
// NewReader returns a new Reader that decompresses from r, using the framing
|
||||
// format described at
|
||||
// https://code.google.com/p/snappy/source/browse/trunk/framing_format.txt
|
||||
// https://github.com/google/snappy/blob/master/framing_format.txt
|
||||
func NewReader(r io.Reader) *Reader {
|
||||
return &Reader{
|
||||
r: r,
|
||||
|
@ -200,7 +204,7 @@ func (r *Reader) Read(p []byte) (int, error) {
|
|||
}
|
||||
|
||||
// The chunk types are specified at
|
||||
// https://code.google.com/p/snappy/source/browse/trunk/framing_format.txt
|
||||
// https://github.com/google/snappy/blob/master/framing_format.txt
|
||||
switch chunkType {
|
||||
case chunkTypeCompressedData:
|
||||
// Section 4.2. Compressed data (chunk type 0x00).
|
||||
|
@ -280,13 +284,11 @@ func (r *Reader) Read(p []byte) (int, error) {
|
|||
// Section 4.5. Reserved unskippable chunks (chunk types 0x02-0x7f).
|
||||
r.err = ErrUnsupported
|
||||
return 0, r.err
|
||||
|
||||
} else {
|
||||
// Section 4.4 Padding (chunk type 0xfe).
|
||||
// Section 4.6. Reserved skippable chunks (chunk types 0x80-0xfd).
|
||||
if !r.readFull(r.buf[:chunkLen]) {
|
||||
return 0, r.err
|
||||
}
|
||||
}
|
||||
// Section 4.4 Padding (chunk type 0xfe).
|
||||
// Section 4.6. Reserved skippable chunks (chunk types 0x80-0xfd).
|
||||
if !r.readFull(r.buf[:chunkLen]) {
|
||||
return 0, r.err
|
||||
}
|
||||
}
|
||||
}
|
|
@ -79,7 +79,7 @@ func emitCopy(dst []byte, offset, length int) int {
|
|||
// slice of dst if dst was large enough to hold the entire encoded block.
|
||||
// Otherwise, a newly allocated slice will be returned.
|
||||
// It is valid to pass a nil dst.
|
||||
func Encode(dst, src []byte) ([]byte, error) {
|
||||
func Encode(dst, src []byte) []byte {
|
||||
if n := MaxEncodedLen(len(src)); len(dst) < n {
|
||||
dst = make([]byte, n)
|
||||
}
|
||||
|
@ -92,7 +92,7 @@ func Encode(dst, src []byte) ([]byte, error) {
|
|||
if len(src) != 0 {
|
||||
d += emitLiteral(dst[d:], src)
|
||||
}
|
||||
return dst[:d], nil
|
||||
return dst[:d]
|
||||
}
|
||||
|
||||
// Initialize the hash table. Its size ranges from 1<<8 to 1<<14 inclusive.
|
||||
|
@ -145,7 +145,7 @@ func Encode(dst, src []byte) ([]byte, error) {
|
|||
if lit != len(src) {
|
||||
d += emitLiteral(dst[d:], src[lit:])
|
||||
}
|
||||
return dst[:d], nil
|
||||
return dst[:d]
|
||||
}
|
||||
|
||||
// MaxEncodedLen returns the maximum length of a snappy block, given its
|
||||
|
@ -176,7 +176,7 @@ func MaxEncodedLen(srcLen int) int {
|
|||
|
||||
// NewWriter returns a new Writer that compresses to w, using the framing
|
||||
// format described at
|
||||
// https://code.google.com/p/snappy/source/browse/trunk/framing_format.txt
|
||||
// https://github.com/google/snappy/blob/master/framing_format.txt
|
||||
func NewWriter(w io.Writer) *Writer {
|
||||
return &Writer{
|
||||
w: w,
|
||||
|
@ -226,11 +226,7 @@ func (w *Writer) Write(p []byte) (n int, errRet error) {
|
|||
// Compress the buffer, discarding the result if the improvement
|
||||
// isn't at least 12.5%.
|
||||
chunkType := uint8(chunkTypeCompressedData)
|
||||
chunkBody, err := Encode(w.enc, uncompressed)
|
||||
if err != nil {
|
||||
w.err = err
|
||||
return n, err
|
||||
}
|
||||
chunkBody := Encode(w.enc, uncompressed)
|
||||
if len(chunkBody) >= len(uncompressed)-len(uncompressed)/8 {
|
||||
chunkType, chunkBody = chunkTypeUncompressedData, uncompressed
|
||||
}
|
||||
|
@ -244,11 +240,11 @@ func (w *Writer) Write(p []byte) (n int, errRet error) {
|
|||
w.buf[5] = uint8(checksum >> 8)
|
||||
w.buf[6] = uint8(checksum >> 16)
|
||||
w.buf[7] = uint8(checksum >> 24)
|
||||
if _, err = w.w.Write(w.buf[:]); err != nil {
|
||||
if _, err := w.w.Write(w.buf[:]); err != nil {
|
||||
w.err = err
|
||||
return n, err
|
||||
}
|
||||
if _, err = w.w.Write(chunkBody); err != nil {
|
||||
if _, err := w.w.Write(chunkBody); err != nil {
|
||||
w.err = err
|
||||
return n, err
|
||||
}
|
|
@ -5,8 +5,8 @@
|
|||
// Package snappy implements the snappy block-based compression format.
|
||||
// It aims for very high speeds and reasonable compression.
|
||||
//
|
||||
// The C++ snappy implementation is at http://code.google.com/p/snappy/
|
||||
package snappy
|
||||
// The C++ snappy implementation is at https://github.com/google/snappy
|
||||
package snappy // import "github.com/golang/snappy"
|
||||
|
||||
import (
|
||||
"hash/crc32"
|
||||
|
@ -46,7 +46,7 @@ const (
|
|||
chunkHeaderSize = 4
|
||||
magicChunk = "\xff\x06\x00\x00" + magicBody
|
||||
magicBody = "sNaPpY"
|
||||
// https://code.google.com/p/snappy/source/browse/trunk/framing_format.txt says
|
||||
// https://github.com/google/snappy/blob/master/framing_format.txt says
|
||||
// that "the uncompressed data in a chunk must be no longer than 65536 bytes".
|
||||
maxUncompressedChunkLen = 65536
|
||||
)
|
||||
|
@ -61,7 +61,7 @@ const (
|
|||
var crcTable = crc32.MakeTable(crc32.Castagnoli)
|
||||
|
||||
// crc implements the checksum specified in section 3 of
|
||||
// https://code.google.com/p/snappy/source/browse/trunk/framing_format.txt
|
||||
// https://github.com/google/snappy/blob/master/framing_format.txt
|
||||
func crc(b []byte) uint32 {
|
||||
c := crc32.Update(0, crcTable, b)
|
||||
return uint32(c>>15|c<<17) + 0xa282ead8
|
|
@ -297,7 +297,7 @@ func main() {
|
|||
|
||||
**NOTE: It might be required to set [Router.HandleMethodNotAllowed](http://godoc.org/github.com/julienschmidt/httprouter#Router.HandleMethodNotAllowed) to `false` to avoid problems.**
|
||||
|
||||
You can use another [http.HandlerFunc](http://golang.org/pkg/net/http/#HandlerFunc), for example another router, to handle requests which could not be matched by this router by using the [Router.NotFound](http://godoc.org/github.com/julienschmidt/httprouter#Router.NotFound) handler. This allows chaining.
|
||||
You can use another [http.Handler](http://golang.org/pkg/net/http/#Handler), for example another router, to handle requests which could not be matched by this router by using the [Router.NotFound](http://godoc.org/github.com/julienschmidt/httprouter#Router.NotFound) handler. This allows chaining.
|
||||
|
||||
### Static files
|
||||
The `NotFound` handler can for example be used to serve static files from the root path `/` (like an index.html file along with other assets):
|
||||
|
|
|
@ -55,7 +55,7 @@
|
|||
//
|
||||
// Catch-all parameters match anything until the path end, including the
|
||||
// directory index (the '/' before the catch-all). Since they match anything
|
||||
// until the end, catch-all paramerters must always be the final path element.
|
||||
// until the end, catch-all parameters must always be the final path element.
|
||||
// Path: /files/*filepath
|
||||
//
|
||||
// Requests:
|
||||
|
@ -138,14 +138,14 @@ type Router struct {
|
|||
// handler.
|
||||
HandleMethodNotAllowed bool
|
||||
|
||||
// Configurable http.HandlerFunc which is called when no matching route is
|
||||
// Configurable http.Handler which is called when no matching route is
|
||||
// found. If it is not set, http.NotFound is used.
|
||||
NotFound http.HandlerFunc
|
||||
NotFound http.Handler
|
||||
|
||||
// Configurable http.HandlerFunc which is called when a request
|
||||
// Configurable http.Handler which is called when a request
|
||||
// cannot be routed and HandleMethodNotAllowed is true.
|
||||
// If it is not set, http.Error with http.StatusMethodNotAllowed is used.
|
||||
MethodNotAllowed http.HandlerFunc
|
||||
MethodNotAllowed http.Handler
|
||||
|
||||
// Function to handle panics recovered from http handlers.
|
||||
// It should be used to generate a error page and return the http error code
|
||||
|
@ -342,7 +342,7 @@ func (r *Router) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
|||
handle, _, _ := r.trees[method].getValue(req.URL.Path)
|
||||
if handle != nil {
|
||||
if r.MethodNotAllowed != nil {
|
||||
r.MethodNotAllowed(w, req)
|
||||
r.MethodNotAllowed.ServeHTTP(w, req)
|
||||
} else {
|
||||
http.Error(w,
|
||||
http.StatusText(http.StatusMethodNotAllowed),
|
||||
|
@ -356,7 +356,7 @@ func (r *Router) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
|||
|
||||
// Handle 404
|
||||
if r.NotFound != nil {
|
||||
r.NotFound(w, req)
|
||||
r.NotFound.ServeHTTP(w, req)
|
||||
} else {
|
||||
http.NotFound(w, req)
|
||||
}
|
||||
|
|
|
@ -291,6 +291,7 @@ func recoverTable(s *session, o *opt.Options) error {
|
|||
|
||||
// We will drop corrupted table.
|
||||
strict = o.GetStrict(opt.StrictRecovery)
|
||||
noSync = o.GetNoSync()
|
||||
|
||||
rec = &sessionRecord{}
|
||||
bpool = util.NewBufferPool(o.GetBlockSize() + 5)
|
||||
|
@ -328,9 +329,11 @@ func recoverTable(s *session, o *opt.Options) error {
|
|||
if err != nil {
|
||||
return
|
||||
}
|
||||
err = writer.Sync()
|
||||
if err != nil {
|
||||
return
|
||||
if !noSync {
|
||||
err = writer.Sync()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
size = int64(tw.BytesLen())
|
||||
return
|
||||
|
|
|
@ -129,7 +129,7 @@ func (db *DB) Write(b *Batch, wo *opt.WriteOptions) (err error) {
|
|||
return
|
||||
}
|
||||
|
||||
b.init(wo.GetSync())
|
||||
b.init(wo.GetSync() && !db.s.o.GetNoSync())
|
||||
|
||||
// The write happen synchronously.
|
||||
select {
|
||||
|
@ -249,8 +249,7 @@ func (db *DB) Put(key, value []byte, wo *opt.WriteOptions) error {
|
|||
return db.Write(b, wo)
|
||||
}
|
||||
|
||||
// Delete deletes the value for the given key. It returns ErrNotFound if
|
||||
// the DB does not contain the key.
|
||||
// Delete deletes the value for the given key.
|
||||
//
|
||||
// It is safe to modify the contents of the arguments after Delete returns.
|
||||
func (db *DB) Delete(key []byte, wo *opt.WriteOptions) error {
|
||||
|
|
|
@ -52,12 +52,14 @@ func IsCorrupted(err error) bool {
|
|||
switch err.(type) {
|
||||
case *ErrCorrupted:
|
||||
return true
|
||||
case *storage.ErrCorrupted:
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// ErrMissingFiles is the type that indicating a corruption due to missing
|
||||
// files.
|
||||
// files. ErrMissingFiles always wrapped with ErrCorrupted.
|
||||
type ErrMissingFiles struct {
|
||||
Files []*storage.FileInfo
|
||||
}
|
||||
|
|
|
@ -308,6 +308,11 @@ type Options struct {
|
|||
// The default is 2.
|
||||
MaxMemCompationLevel int
|
||||
|
||||
// NoSync allows completely disable fsync.
|
||||
//
|
||||
// The default is false.
|
||||
NoSync bool
|
||||
|
||||
// NumLevel defines number of database level. The level shouldn't changed
|
||||
// between opens, or the database will panic.
|
||||
//
|
||||
|
@ -546,6 +551,13 @@ func (o *Options) GetMaxMemCompationLevel() int {
|
|||
return level
|
||||
}
|
||||
|
||||
func (o *Options) GetNoSync() bool {
|
||||
if o == nil {
|
||||
return false
|
||||
}
|
||||
return o.NoSync
|
||||
}
|
||||
|
||||
func (o *Options) GetNumLevel() int {
|
||||
if o == nil || o.NumLevel <= 0 {
|
||||
return DefaultNumLevel
|
||||
|
|
|
@ -240,9 +240,11 @@ func (s *session) flushManifest(rec *sessionRecord) (err error) {
|
|||
if err != nil {
|
||||
return
|
||||
}
|
||||
err = s.manifestWriter.Sync()
|
||||
if err != nil {
|
||||
return
|
||||
if !s.o.GetNoSync() {
|
||||
err = s.manifestWriter.Sync()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
s.recordCommited(rec)
|
||||
return
|
||||
|
|
|
@ -243,7 +243,10 @@ func (fs *fileStorage) GetManifest() (f File, err error) {
|
|||
rem = append(rem, fn)
|
||||
}
|
||||
if !pend1 || cerr == nil {
|
||||
cerr = fmt.Errorf("leveldb/storage: corrupted or incomplete %s file", fn)
|
||||
cerr = &ErrCorrupted{
|
||||
File: fsParseName(filepath.Base(fn)),
|
||||
Err: errors.New("leveldb/storage: corrupted or incomplete manifest file"),
|
||||
}
|
||||
}
|
||||
} else if f != nil && f1.Num() < f.Num() {
|
||||
fs.log(fmt.Sprintf("skipping %s: obsolete", fn))
|
||||
|
@ -326,8 +329,7 @@ func (fs *fileStorage) Close() error {
|
|||
runtime.SetFinalizer(fs, nil)
|
||||
|
||||
if fs.open > 0 {
|
||||
fs.log(fmt.Sprintf("refuse to close, %d files still open", fs.open))
|
||||
return fmt.Errorf("leveldb/storage: cannot close, %d files still open", fs.open)
|
||||
fs.log(fmt.Sprintf("close: warning, %d files still open", fs.open))
|
||||
}
|
||||
fs.open = -1
|
||||
e1 := fs.logw.Close()
|
||||
|
@ -505,30 +507,37 @@ func (f *file) path() string {
|
|||
return filepath.Join(f.fs.path, f.name())
|
||||
}
|
||||
|
||||
func (f *file) parse(name string) bool {
|
||||
var num uint64
|
||||
func fsParseName(name string) *FileInfo {
|
||||
fi := &FileInfo{}
|
||||
var tail string
|
||||
_, err := fmt.Sscanf(name, "%d.%s", &num, &tail)
|
||||
_, err := fmt.Sscanf(name, "%d.%s", &fi.Num, &tail)
|
||||
if err == nil {
|
||||
switch tail {
|
||||
case "log":
|
||||
f.t = TypeJournal
|
||||
fi.Type = TypeJournal
|
||||
case "ldb", "sst":
|
||||
f.t = TypeTable
|
||||
fi.Type = TypeTable
|
||||
case "tmp":
|
||||
f.t = TypeTemp
|
||||
fi.Type = TypeTemp
|
||||
default:
|
||||
return false
|
||||
return nil
|
||||
}
|
||||
f.num = num
|
||||
return true
|
||||
return fi
|
||||
}
|
||||
n, _ := fmt.Sscanf(name, "MANIFEST-%d%s", &num, &tail)
|
||||
n, _ := fmt.Sscanf(name, "MANIFEST-%d%s", &fi.Num, &tail)
|
||||
if n == 1 {
|
||||
f.t = TypeManifest
|
||||
f.num = num
|
||||
return true
|
||||
fi.Type = TypeManifest
|
||||
return fi
|
||||
}
|
||||
|
||||
return false
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *file) parse(name string) bool {
|
||||
fi := fsParseName(name)
|
||||
if fi == nil {
|
||||
return false
|
||||
}
|
||||
f.t = fi.Type
|
||||
f.num = fi.Num
|
||||
return true
|
||||
}
|
||||
|
|
|
@ -50,13 +50,23 @@ func rename(oldpath, newpath string) error {
|
|||
return os.Rename(oldpath, newpath)
|
||||
}
|
||||
|
||||
func isErrInvalid(err error) bool {
|
||||
if err == os.ErrInvalid {
|
||||
return true
|
||||
}
|
||||
if syserr, ok := err.(*os.SyscallError); ok && syserr.Err == syscall.EINVAL {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func syncDir(name string) error {
|
||||
f, err := os.Open(name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer f.Close()
|
||||
if err := f.Sync(); err != nil {
|
||||
if err := f.Sync(); err != nil && !isErrInvalid(err) {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
|
|
|
@ -46,6 +46,22 @@ var (
|
|||
ErrClosed = errors.New("leveldb/storage: closed")
|
||||
)
|
||||
|
||||
// ErrCorrupted is the type that wraps errors that indicate corruption of
|
||||
// a file. Package storage has its own type instead of using
|
||||
// errors.ErrCorrupted to prevent circular import.
|
||||
type ErrCorrupted struct {
|
||||
File *FileInfo
|
||||
Err error
|
||||
}
|
||||
|
||||
func (e *ErrCorrupted) Error() string {
|
||||
if e.File != nil {
|
||||
return fmt.Sprintf("%v [file=%v]", e.Err, e.File)
|
||||
} else {
|
||||
return e.Err.Error()
|
||||
}
|
||||
}
|
||||
|
||||
// Syncer is the interface that wraps basic Sync method.
|
||||
type Syncer interface {
|
||||
// Sync commits the current contents of the file to stable storage.
|
||||
|
|
|
@ -287,6 +287,7 @@ func (x *tFilesSortByNum) Less(i, j int) bool {
|
|||
// Table operations.
|
||||
type tOps struct {
|
||||
s *session
|
||||
noSync bool
|
||||
cache *cache.Cache
|
||||
bcache *cache.Cache
|
||||
bpool *util.BufferPool
|
||||
|
@ -458,6 +459,7 @@ func newTableOps(s *session) *tOps {
|
|||
}
|
||||
return &tOps{
|
||||
s: s,
|
||||
noSync: s.o.GetNoSync(),
|
||||
cache: cache.NewCache(cacher),
|
||||
bcache: bcache,
|
||||
bpool: bpool,
|
||||
|
@ -505,9 +507,11 @@ func (w *tWriter) finish() (f *tFile, err error) {
|
|||
if err != nil {
|
||||
return
|
||||
}
|
||||
err = w.w.Sync()
|
||||
if err != nil {
|
||||
return
|
||||
if !w.t.noSync {
|
||||
err = w.w.Sync()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
f = newTableFile(w.file, uint64(w.tw.BytesLen()), iKey(w.first), iKey(w.last))
|
||||
return
|
||||
|
|
|
@ -14,7 +14,7 @@ import (
|
|||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/syndtr/gosnappy/snappy"
|
||||
"github.com/golang/snappy"
|
||||
|
||||
"github.com/syndtr/goleveldb/leveldb/cache"
|
||||
"github.com/syndtr/goleveldb/leveldb/comparer"
|
||||
|
|
|
@ -12,7 +12,7 @@ import (
|
|||
"fmt"
|
||||
"io"
|
||||
|
||||
"github.com/syndtr/gosnappy/snappy"
|
||||
"github.com/golang/snappy"
|
||||
|
||||
"github.com/syndtr/goleveldb/leveldb/comparer"
|
||||
"github.com/syndtr/goleveldb/leveldb/filter"
|
||||
|
@ -167,11 +167,7 @@ func (w *Writer) writeBlock(buf *util.Buffer, compression opt.Compression) (bh b
|
|||
if n := snappy.MaxEncodedLen(buf.Len()) + blockTrailerLen; len(w.compressionScratch) < n {
|
||||
w.compressionScratch = make([]byte, n)
|
||||
}
|
||||
var compressed []byte
|
||||
compressed, err = snappy.Encode(w.compressionScratch, buf.Bytes())
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
compressed := snappy.Encode(w.compressionScratch, buf.Bytes())
|
||||
n := len(compressed)
|
||||
b = compressed[:n+blockTrailerLen]
|
||||
b[n] = blockTypeSnappyCompression
|
||||
|
|
|
@ -201,6 +201,7 @@ func (p *BufferPool) String() string {
|
|||
|
||||
func (p *BufferPool) drain() {
|
||||
ticker := time.NewTicker(2 * time.Second)
|
||||
defer ticker.Stop()
|
||||
for {
|
||||
select {
|
||||
case <-ticker.C:
|
||||
|
|
|
@ -1019,7 +1019,7 @@ func yaml_emitter_analyze_scalar(emitter *yaml_emitter_t, value []byte) bool {
|
|||
|
||||
preceeded_by_whitespace = true
|
||||
for i, w := 0, 0; i < len(value); i += w {
|
||||
w = width(value[0])
|
||||
w = width(value[i])
|
||||
followed_by_whitespace = i+w >= len(value) || is_blank(value, i+w)
|
||||
|
||||
if i == 0 {
|
||||
|
|
|
@ -324,13 +324,15 @@ func isZero(v reflect.Value) bool {
|
|||
return v.Len() == 0
|
||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||
return v.Int() == 0
|
||||
case reflect.Float32, reflect.Float64:
|
||||
return v.Float() == 0
|
||||
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
|
||||
return v.Uint() == 0
|
||||
case reflect.Bool:
|
||||
return !v.Bool()
|
||||
case reflect.Struct:
|
||||
vt := v.Type()
|
||||
for i := v.NumField()-1; i >= 0; i-- {
|
||||
for i := v.NumField() - 1; i >= 0; i-- {
|
||||
if vt.Field(i).PkgPath != "" {
|
||||
continue // Private field
|
||||
}
|
||||
|
|
|
@ -0,0 +1,106 @@
|
|||
{
|
||||
"comment": "",
|
||||
"ignore": "test",
|
||||
"package": [
|
||||
{
|
||||
"path": "github.com/Sirupsen/logrus",
|
||||
"revision": "418b41d23a1bf978c06faea5313ba194650ac088",
|
||||
"revisionTime": "2015-09-08T20:46:18Z"
|
||||
},
|
||||
{
|
||||
"path": "github.com/golang/snappy",
|
||||
"revision": "723cc1e459b8eea2dea4583200fd60757d40097a",
|
||||
"revisionTime": "2015-07-30T13:18:44+10:00"
|
||||
},
|
||||
{
|
||||
"path": "github.com/julienschmidt/httprouter",
|
||||
"revision": "109e267447e95ad1bb48b758e40dd7453eb7b039",
|
||||
"revisionTime": "2015-09-05T19:25:33+02:00"
|
||||
},
|
||||
{
|
||||
"path": "github.com/prometheus/common/model",
|
||||
"revision": "51d43993bd4018e9470540600641285cad786840",
|
||||
"revisionTime": "2015-09-22T12:03:38+02:00"
|
||||
},
|
||||
{
|
||||
"path": "github.com/prometheus/common/route",
|
||||
"revision": "51d43993bd4018e9470540600641285cad786840",
|
||||
"revisionTime": "2015-09-22T12:03:38+02:00"
|
||||
},
|
||||
{
|
||||
"path": "github.com/prometheus/log",
|
||||
"revision": "439e5db48fbb50ebbaf2c816030473a62f505f55",
|
||||
"revisionTime": "2015-05-29T14:22:02+02:00"
|
||||
},
|
||||
{
|
||||
"path": "github.com/syndtr/goleveldb/leveldb",
|
||||
"revision": "1a9d62f03ea92815b46fcaab357cfd4df264b1a0",
|
||||
"revisionTime": "2015-08-19T12:16:22+07:00"
|
||||
},
|
||||
{
|
||||
"path": "github.com/syndtr/goleveldb/leveldb/cache",
|
||||
"revision": "1a9d62f03ea92815b46fcaab357cfd4df264b1a0",
|
||||
"revisionTime": "2015-08-19T12:16:22+07:00"
|
||||
},
|
||||
{
|
||||
"path": "github.com/syndtr/goleveldb/leveldb/comparer",
|
||||
"revision": "1a9d62f03ea92815b46fcaab357cfd4df264b1a0",
|
||||
"revisionTime": "2015-08-19T12:16:22+07:00"
|
||||
},
|
||||
{
|
||||
"path": "github.com/syndtr/goleveldb/leveldb/errors",
|
||||
"revision": "1a9d62f03ea92815b46fcaab357cfd4df264b1a0",
|
||||
"revisionTime": "2015-08-19T12:16:22+07:00"
|
||||
},
|
||||
{
|
||||
"path": "github.com/syndtr/goleveldb/leveldb/filter",
|
||||
"revision": "1a9d62f03ea92815b46fcaab357cfd4df264b1a0",
|
||||
"revisionTime": "2015-08-19T12:16:22+07:00"
|
||||
},
|
||||
{
|
||||
"path": "github.com/syndtr/goleveldb/leveldb/iterator",
|
||||
"revision": "1a9d62f03ea92815b46fcaab357cfd4df264b1a0",
|
||||
"revisionTime": "2015-08-19T12:16:22+07:00"
|
||||
},
|
||||
{
|
||||
"path": "github.com/syndtr/goleveldb/leveldb/journal",
|
||||
"revision": "1a9d62f03ea92815b46fcaab357cfd4df264b1a0",
|
||||
"revisionTime": "2015-08-19T12:16:22+07:00"
|
||||
},
|
||||
{
|
||||
"path": "github.com/syndtr/goleveldb/leveldb/memdb",
|
||||
"revision": "1a9d62f03ea92815b46fcaab357cfd4df264b1a0",
|
||||
"revisionTime": "2015-08-19T12:16:22+07:00"
|
||||
},
|
||||
{
|
||||
"path": "github.com/syndtr/goleveldb/leveldb/opt",
|
||||
"revision": "1a9d62f03ea92815b46fcaab357cfd4df264b1a0",
|
||||
"revisionTime": "2015-08-19T12:16:22+07:00"
|
||||
},
|
||||
{
|
||||
"path": "github.com/syndtr/goleveldb/leveldb/storage",
|
||||
"revision": "1a9d62f03ea92815b46fcaab357cfd4df264b1a0",
|
||||
"revisionTime": "2015-08-19T12:16:22+07:00"
|
||||
},
|
||||
{
|
||||
"path": "github.com/syndtr/goleveldb/leveldb/table",
|
||||
"revision": "1a9d62f03ea92815b46fcaab357cfd4df264b1a0",
|
||||
"revisionTime": "2015-08-19T12:16:22+07:00"
|
||||
},
|
||||
{
|
||||
"path": "github.com/syndtr/goleveldb/leveldb/util",
|
||||
"revision": "1a9d62f03ea92815b46fcaab357cfd4df264b1a0",
|
||||
"revisionTime": "2015-08-19T12:16:22+07:00"
|
||||
},
|
||||
{
|
||||
"path": "golang.org/x/net/context",
|
||||
"revision": "db8e4de5b2d6653f66aea53094624468caad15d2",
|
||||
"revisionTime": "2015-08-24T18:07:02+02:00"
|
||||
},
|
||||
{
|
||||
"path": "gopkg.in/yaml.v2",
|
||||
"revision": "7ad95dd0798a40da1ccdff6dff35fd177b5edf40",
|
||||
"revisionTime": "2015-06-24T11:29:02+01:00"
|
||||
}
|
||||
]
|
||||
}
|
Loading…
Reference in New Issue