mirror of
https://github.com/fluencelabs/tendermint
synced 2025-06-03 08:31:20 +00:00
Merge branch 'develop' into 45-change-common-start-signature
This commit is contained in:
commit
ddd141c1c5
19
.editorconfig
Normal file
19
.editorconfig
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
# top-most EditorConfig file
|
||||||
|
root = true
|
||||||
|
|
||||||
|
# Unix-style newlines with a newline ending every file
|
||||||
|
[*]
|
||||||
|
charset = utf-8
|
||||||
|
end_of_line = lf
|
||||||
|
insert_final_newline = true
|
||||||
|
trim_trailing_whitespace = true
|
||||||
|
|
||||||
|
[Makefile]
|
||||||
|
indent_style = tab
|
||||||
|
|
||||||
|
[*.sh]
|
||||||
|
indent_style = tab
|
||||||
|
|
||||||
|
[*.proto]
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 2
|
12
CHANGELOG.md
12
CHANGELOG.md
@ -1,5 +1,17 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## 0.4.1 (November 27, 2017)
|
||||||
|
|
||||||
|
FEATURES:
|
||||||
|
- [common] `Keys()` method on `CMap`
|
||||||
|
|
||||||
|
IMPROVEMENTS:
|
||||||
|
- [log] complex types now encoded as "%+v" by default if `String()` method is undefined (previously resulted in error)
|
||||||
|
- [log] logger logs its own errors
|
||||||
|
|
||||||
|
BUG FIXES:
|
||||||
|
- [common] fixed `Kill()` to build on Windows (Windows does not have `syscall.Kill`)
|
||||||
|
|
||||||
## 0.4.0 (October 26, 2017)
|
## 0.4.0 (October 26, 2017)
|
||||||
|
|
||||||
BREAKING:
|
BREAKING:
|
||||||
|
@ -149,7 +149,7 @@ func _TestGCRandom(t *testing.T) {
|
|||||||
func TestScanRightDeleteRandom(t *testing.T) {
|
func TestScanRightDeleteRandom(t *testing.T) {
|
||||||
|
|
||||||
const numElements = 10000
|
const numElements = 10000
|
||||||
const numTimes = 100000
|
const numTimes = 1000
|
||||||
const numScanners = 10
|
const numScanners = 10
|
||||||
|
|
||||||
l := New()
|
l := New()
|
||||||
|
@ -2,6 +2,7 @@ package db
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
)
|
)
|
||||||
@ -127,6 +128,8 @@ func (db *MemDB) IteratorPrefix(prefix []byte) Iterator {
|
|||||||
it.keys = append(it.keys, key)
|
it.keys = append(it.keys, key)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// and we need to sort them
|
||||||
|
sort.Strings(it.keys)
|
||||||
return it
|
return it
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,19 +52,28 @@ func NewTMLoggerWithColorFn(w io.Writer, colorFn func(keyvals ...interface{}) te
|
|||||||
// Info logs a message at level Info.
|
// Info logs a message at level Info.
|
||||||
func (l *tmLogger) Info(msg string, keyvals ...interface{}) {
|
func (l *tmLogger) Info(msg string, keyvals ...interface{}) {
|
||||||
lWithLevel := kitlevel.Info(l.srcLogger)
|
lWithLevel := kitlevel.Info(l.srcLogger)
|
||||||
kitlog.With(lWithLevel, msgKey, msg).Log(keyvals...)
|
if err := kitlog.With(lWithLevel, msgKey, msg).Log(keyvals...); err != nil {
|
||||||
|
errLogger := kitlevel.Error(l.srcLogger)
|
||||||
|
kitlog.With(errLogger, msgKey, msg).Log("err", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Debug logs a message at level Debug.
|
// Debug logs a message at level Debug.
|
||||||
func (l *tmLogger) Debug(msg string, keyvals ...interface{}) {
|
func (l *tmLogger) Debug(msg string, keyvals ...interface{}) {
|
||||||
lWithLevel := kitlevel.Debug(l.srcLogger)
|
lWithLevel := kitlevel.Debug(l.srcLogger)
|
||||||
kitlog.With(lWithLevel, msgKey, msg).Log(keyvals...)
|
if err := kitlog.With(lWithLevel, msgKey, msg).Log(keyvals...); err != nil {
|
||||||
|
errLogger := kitlevel.Error(l.srcLogger)
|
||||||
|
kitlog.With(errLogger, msgKey, msg).Log("err", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Error logs a message at level Error.
|
// Error logs a message at level Error.
|
||||||
func (l *tmLogger) Error(msg string, keyvals ...interface{}) {
|
func (l *tmLogger) Error(msg string, keyvals ...interface{}) {
|
||||||
lWithLevel := kitlevel.Error(l.srcLogger)
|
lWithLevel := kitlevel.Error(l.srcLogger)
|
||||||
kitlog.With(lWithLevel, msgKey, msg).Log(keyvals...)
|
lWithMsg := kitlog.With(lWithLevel, msgKey, msg)
|
||||||
|
if err := lWithMsg.Log(keyvals...); err != nil {
|
||||||
|
lWithMsg.Log("err", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// With returns a new contextual logger with keyvals prepended to those passed
|
// With returns a new contextual logger with keyvals prepended to those passed
|
||||||
|
@ -1,12 +1,26 @@
|
|||||||
package log_test
|
package log_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/go-logfmt/logfmt"
|
||||||
"github.com/tendermint/tmlibs/log"
|
"github.com/tendermint/tmlibs/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func TestLoggerLogsItsErrors(t *testing.T) {
|
||||||
|
var buf bytes.Buffer
|
||||||
|
|
||||||
|
logger := log.NewTMLogger(&buf)
|
||||||
|
logger.Info("foo", "baz baz", "bar")
|
||||||
|
msg := strings.TrimSpace(buf.String())
|
||||||
|
if !strings.Contains(msg, logfmt.ErrInvalidKey.Error()) {
|
||||||
|
t.Errorf("Expected logger msg to contain ErrInvalidKey, got %s", msg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func BenchmarkTMLoggerSimple(b *testing.B) {
|
func BenchmarkTMLoggerSimple(b *testing.B) {
|
||||||
benchmarkRunner(b, log.NewTMLogger(ioutil.Discard), baseInfoMessage)
|
benchmarkRunner(b, log.NewTMLogger(ioutil.Discard), baseInfoMessage)
|
||||||
}
|
}
|
||||||
|
@ -35,7 +35,8 @@ type tmfmtLogger struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NewTMFmtLogger returns a logger that encodes keyvals to the Writer in
|
// NewTMFmtLogger returns a logger that encodes keyvals to the Writer in
|
||||||
// Tendermint custom format.
|
// Tendermint custom format. Note complex types (structs, maps, slices)
|
||||||
|
// formatted as "%+v".
|
||||||
//
|
//
|
||||||
// Each log event produces no more than one call to w.Write.
|
// Each log event produces no more than one call to w.Write.
|
||||||
// The passed Writer must be safe for concurrent use by multiple goroutines if
|
// The passed Writer must be safe for concurrent use by multiple goroutines if
|
||||||
@ -103,7 +104,10 @@ KeyvalueLoop:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := enc.EncodeKeyval(keyvals[i], keyvals[i+1]); err != nil {
|
err := enc.EncodeKeyval(keyvals[i], keyvals[i+1])
|
||||||
|
if err == logfmt.ErrUnsupportedValueType {
|
||||||
|
enc.EncodeKeyval(keyvals[i], fmt.Sprintf("%+v", keyvals[i+1]))
|
||||||
|
} else if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -30,8 +30,10 @@ func TestTMFmtLogger(t *testing.T) {
|
|||||||
assert.Regexp(t, regexp.MustCompile(`N\[.+\] unknown \s+ a=1 err=error\n$`), buf.String())
|
assert.Regexp(t, regexp.MustCompile(`N\[.+\] unknown \s+ a=1 err=error\n$`), buf.String())
|
||||||
|
|
||||||
buf.Reset()
|
buf.Reset()
|
||||||
err := logger.Log("std_map", map[int]int{1: 2}, "my_map", mymap{0: 0})
|
if err := logger.Log("std_map", map[int]int{1: 2}, "my_map", mymap{0: 0}); err != nil {
|
||||||
assert.NotNil(t, err)
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
assert.Regexp(t, regexp.MustCompile(`N\[.+\] unknown \s+ std_map=map\[1:2\] my_map=special_behavior\n$`), buf.String())
|
||||||
|
|
||||||
buf.Reset()
|
buf.Reset()
|
||||||
if err := logger.Log("level", "error"); err != nil {
|
if err := logger.Log("level", "error"); err != nil {
|
||||||
|
@ -1,76 +0,0 @@
|
|||||||
package process
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"os"
|
|
||||||
"os/exec"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Process struct {
|
|
||||||
Label string
|
|
||||||
ExecPath string
|
|
||||||
Args []string
|
|
||||||
Pid int
|
|
||||||
StartTime time.Time
|
|
||||||
EndTime time.Time
|
|
||||||
Cmd *exec.Cmd `json:"-"`
|
|
||||||
ExitState *os.ProcessState `json:"-"`
|
|
||||||
InputFile io.Reader `json:"-"`
|
|
||||||
OutputFile io.WriteCloser `json:"-"`
|
|
||||||
WaitCh chan struct{} `json:"-"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// execPath: command name
|
|
||||||
// args: args to command. (should not include name)
|
|
||||||
func StartProcess(label string, dir string, execPath string, args []string, inFile io.Reader, outFile io.WriteCloser) (*Process, error) {
|
|
||||||
cmd := exec.Command(execPath, args...)
|
|
||||||
cmd.Dir = dir
|
|
||||||
cmd.Stdout = outFile
|
|
||||||
cmd.Stderr = outFile
|
|
||||||
cmd.Stdin = inFile
|
|
||||||
if err := cmd.Start(); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
proc := &Process{
|
|
||||||
Label: label,
|
|
||||||
ExecPath: execPath,
|
|
||||||
Args: args,
|
|
||||||
Pid: cmd.Process.Pid,
|
|
||||||
StartTime: time.Now(),
|
|
||||||
Cmd: cmd,
|
|
||||||
ExitState: nil,
|
|
||||||
InputFile: inFile,
|
|
||||||
OutputFile: outFile,
|
|
||||||
WaitCh: make(chan struct{}),
|
|
||||||
}
|
|
||||||
go func() {
|
|
||||||
err := proc.Cmd.Wait()
|
|
||||||
if err != nil {
|
|
||||||
// fmt.Printf("Process exit: %v\n", err)
|
|
||||||
if exitError, ok := err.(*exec.ExitError); ok {
|
|
||||||
proc.ExitState = exitError.ProcessState
|
|
||||||
}
|
|
||||||
}
|
|
||||||
proc.ExitState = proc.Cmd.ProcessState
|
|
||||||
proc.EndTime = time.Now() // TODO make this goroutine-safe
|
|
||||||
err = proc.OutputFile.Close()
|
|
||||||
if err != nil {
|
|
||||||
fmt.Printf("Error closing output file for %v: %v\n", proc.Label, err)
|
|
||||||
}
|
|
||||||
close(proc.WaitCh)
|
|
||||||
}()
|
|
||||||
return proc, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (proc *Process) StopProcess(kill bool) error {
|
|
||||||
defer proc.OutputFile.Close()
|
|
||||||
if kill {
|
|
||||||
// fmt.Printf("Killing process %v\n", proc.Cmd.Process)
|
|
||||||
return proc.Cmd.Process.Kill()
|
|
||||||
} else {
|
|
||||||
// fmt.Printf("Stopping process %v\n", proc.Cmd.Process)
|
|
||||||
return proc.Cmd.Process.Signal(os.Interrupt)
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,22 +0,0 @@
|
|||||||
package process
|
|
||||||
|
|
||||||
import (
|
|
||||||
. "github.com/tendermint/tmlibs/common"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Runs a command and gets the result.
|
|
||||||
func Run(dir string, command string, args []string) (string, bool, error) {
|
|
||||||
outFile := NewBufferCloser(nil)
|
|
||||||
proc, err := StartProcess("", dir, command, args, nil, outFile)
|
|
||||||
if err != nil {
|
|
||||||
return "", false, err
|
|
||||||
}
|
|
||||||
|
|
||||||
<-proc.WaitCh
|
|
||||||
|
|
||||||
if proc.ExitState.Success() {
|
|
||||||
return outFile.String(), true, nil
|
|
||||||
} else {
|
|
||||||
return outFile.String(), false, nil
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,3 +1,3 @@
|
|||||||
package version
|
package version
|
||||||
|
|
||||||
const Version = "0.4.0"
|
const Version = "0.4.1"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user