Commit 51fd99e3 authored by Jeromy's avatar Jeromy
Browse files

extract from 0.4.0

parent 5a0162c7
package protocol
import (
"io"
msgio "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-msgio"
)
// ID is an identifier used to write protocol headers in streams.
type ID string
......@@ -13,28 +7,3 @@ type ID string
const (
TestingID ID = "/p2p/_testing"
)
// WriteHeader writes a protocol.ID header to an io.Writer. This is so
// multiple protocols can be multiplexed on top of the same transport.
//
// We use go-msgio varint encoding:
// <varint length><string name>\n
// (the varint includes the \n)
func WriteHeader(w io.Writer, id ID) error {
vw := msgio.NewVarintWriter(w)
s := string(id) + "\n" // add \n
return vw.WriteMsg([]byte(s))
}
// ReadHeader reads a protocol.ID header from an io.Reader. This is so
// multiple protocols can be multiplexed on top of the same transport.
// See WriteHeader.
func ReadHeader(r io.Reader) (ID, error) {
vr := msgio.NewVarintReader(r)
msg, err := vr.ReadMsg()
if err != nil {
return ID(""), err
}
msg = msg[:len(msg)-1] // remove \n
return ID(msg), nil
}
......@@ -4,16 +4,16 @@ import (
"fmt"
"io"
mh "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multihash"
mh "github.com/jbenet/go-multihash"
logging "github.com/ipfs/go-ipfs/vendor/go-log-v1.0.0"
host "github.com/ipfs/go-libp2p/p2p/host"
inet "github.com/ipfs/go-libp2p/p2p/net"
peer "github.com/ipfs/go-libp2p/p2p/peer"
protocol "github.com/ipfs/go-libp2p/p2p/protocol"
logging "QmWRypnfEwrgH4k93KEHN5hng7VjKYkWmzDYRuTZeh2Mgh/go-log"
)
var log = logging.Logger("p2p/protocol/relay")
var log = logging.Logger("github.com/ipfs/go-libp2p/p2p/protocol/relay")
// ID is the protocol.ID of the Relay Service.
const ID protocol.ID = "/ipfs/relay"
......
......@@ -4,13 +4,14 @@ import (
"io"
"testing"
logging "github.com/ipfs/go-ipfs/vendor/go-log-v1.0.0"
inet "github.com/ipfs/go-libp2p/p2p/net"
protocol "github.com/ipfs/go-libp2p/p2p/protocol"
relay "github.com/ipfs/go-libp2p/p2p/protocol/relay"
testutil "github.com/ipfs/go-libp2p/p2p/test/util"
logging "QmWRypnfEwrgH4k93KEHN5hng7VjKYkWmzDYRuTZeh2Mgh/go-log"
context "github.com/ipfs/go-ipfs/Godeps/_workspace/src/golang.org/x/net/context"
msmux "github.com/whyrusleeping/go-multistream"
context "golang.org/x/net/context"
)
var log = logging.Logger("relay_test")
......@@ -62,7 +63,7 @@ func TestRelaySimple(t *testing.T) {
// ok now the header's there, we can write the next protocol header.
log.Debug("write testing header")
if err := protocol.WriteHeader(s, protocol.TestingID); err != nil {
if err := msmux.SelectProtoOrFail(string(protocol.TestingID), s); err != nil {
t.Fatal(err)
}
......@@ -155,7 +156,7 @@ func TestRelayAcrossFour(t *testing.T) {
}
log.Debugf("write relay header n1->n4 (%s -> %s)", n1p, n4p)
if err := protocol.WriteHeader(s, relay.ID); err != nil {
if err := msmux.SelectProtoOrFail(string(relay.ID), s); err != nil {
t.Fatal(err)
}
if err := relay.WriteHeader(s, n1p, n4p); err != nil {
......@@ -163,7 +164,7 @@ func TestRelayAcrossFour(t *testing.T) {
}
log.Debugf("write relay header n1->n5 (%s -> %s)", n1p, n5p)
if err := protocol.WriteHeader(s, relay.ID); err != nil {
if err := msmux.SelectProtoOrFail(string(relay.ID), s); err != nil {
t.Fatal(err)
}
if err := relay.WriteHeader(s, n1p, n5p); err != nil {
......@@ -172,7 +173,7 @@ func TestRelayAcrossFour(t *testing.T) {
// ok now the header's there, we can write the next protocol header.
log.Debug("write testing header")
if err := protocol.WriteHeader(s, protocol.TestingID); err != nil {
if err := msmux.SelectProtoOrFail(string(protocol.TestingID), s); err != nil {
t.Fatal(err)
}
......@@ -257,7 +258,7 @@ func TestRelayStress(t *testing.T) {
// ok now the header's there, we can write the next protocol header.
log.Debug("write testing header")
if err := protocol.WriteHeader(s, protocol.TestingID); err != nil {
if err := msmux.SelectProtoOrFail(string(protocol.TestingID), s); err != nil {
t.Fatal(err)
}
......
......@@ -6,15 +6,15 @@ import (
"testing"
"time"
logging "github.com/ipfs/go-ipfs/vendor/go-log-v1.0.0"
host "github.com/ipfs/go-libp2p/p2p/host"
inet "github.com/ipfs/go-libp2p/p2p/net"
peer "github.com/ipfs/go-libp2p/p2p/peer"
protocol "github.com/ipfs/go-libp2p/p2p/protocol"
testutil "github.com/ipfs/go-libp2p/p2p/test/util"
logging "QmWRypnfEwrgH4k93KEHN5hng7VjKYkWmzDYRuTZeh2Mgh/go-log"
context "github.com/ipfs/go-ipfs/Godeps/_workspace/src/golang.org/x/net/context"
u "github.com/ipfs/go-ipfs/util"
context "golang.org/x/net/context"
u "util"
)
var log = logging.Logger("backpressure")
......@@ -299,6 +299,12 @@ func TestStBackpressureStreamWrite(t *testing.T) {
}
}
// trigger lazy connection handshaking
_, err = s.Read(nil)
if err != nil {
t.Fatal(err)
}
// 500ms rounds of lockstep write + drain
roundsStart := time.Now()
roundsTotal := 0
......
......@@ -7,16 +7,16 @@ import (
"testing"
"time"
u "github.com/ipfs/go-ipfs/util"
logging "github.com/ipfs/go-ipfs/vendor/go-log-v1.0.0"
host "github.com/ipfs/go-libp2p/p2p/host"
inet "github.com/ipfs/go-libp2p/p2p/net"
swarm "github.com/ipfs/go-libp2p/p2p/net/swarm"
protocol "github.com/ipfs/go-libp2p/p2p/protocol"
testutil "github.com/ipfs/go-libp2p/p2p/test/util"
u "util"
logging "QmWRypnfEwrgH4k93KEHN5hng7VjKYkWmzDYRuTZeh2Mgh/go-log"
ps "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-peerstream"
context "github.com/ipfs/go-ipfs/Godeps/_workspace/src/golang.org/x/net/context"
ps "github.com/jbenet/go-peerstream"
context "golang.org/x/net/context"
)
func init() {
......
......@@ -5,14 +5,14 @@ import (
"io"
"testing"
u "github.com/ipfs/go-ipfs/util"
testutil "github.com/ipfs/go-ipfs/util/testutil"
logging "github.com/ipfs/go-ipfs/vendor/go-log-v1.0.0"
u "util"
testutil "util/testutil"
logging "QmWRypnfEwrgH4k93KEHN5hng7VjKYkWmzDYRuTZeh2Mgh/go-log"
ic "github.com/ipfs/go-libp2p/p2p/crypto"
peer "github.com/ipfs/go-libp2p/p2p/peer"
ma "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr"
ma "github.com/jbenet/go-multiaddr"
)
var log = logging.Logger("boguskey")
......
......@@ -3,15 +3,15 @@ package testutil
import (
"testing"
tu "github.com/ipfs/go-ipfs/util/testutil"
bhost "github.com/ipfs/go-libp2p/p2p/host/basic"
metrics "github.com/ipfs/go-libp2p/p2p/metrics"
inet "github.com/ipfs/go-libp2p/p2p/net"
swarm "github.com/ipfs/go-libp2p/p2p/net/swarm"
peer "github.com/ipfs/go-libp2p/p2p/peer"
metrics "github.com/ipfs/go-libp2p/util/metrics"
tu "util/testutil"
ma "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr"
context "github.com/ipfs/go-ipfs/Godeps/_workspace/src/golang.org/x/net/context"
ma "github.com/jbenet/go-multiaddr"
context "golang.org/x/net/context"
)
func GenSwarmNetwork(t *testing.T, ctx context.Context) *swarm.Network {
......
{
"name": "go-libp2p",
"author": "joe",
"version": "1.0.0",
"gxDependencies": [
{
"name": "go-log",
"hash": "QmWRypnfEwrgH4k93KEHN5hng7VjKYkWmzDYRuTZeh2Mgh",
"version": "1.0.0"
},
{
"name": "go-keyspace",
"hash": "Qma4vHVBYKDiKS5VpvtLNJHHDbL7S6VRsvxxmBnBFfKP3k",
"version": "1.0.0"
}
],
"language": "go"
}
\ No newline at end of file
1.0.0: QmQg1J6vikuXF9oDvm4wpdeAUvvkVEKW1EYDw9HhTMnP2b
package log
import (
"errors"
"golang.org/x/net/context"
)
type key int
const metadataKey key = 0
// ContextWithLoggable returns a derived context which contains the provided
// Loggable. Any Events logged with the derived context will include the
// provided Loggable.
func ContextWithLoggable(ctx context.Context, l Loggable) context.Context {
existing, err := MetadataFromContext(ctx)
if err != nil {
// context does not contain meta. just set the new metadata
child := context.WithValue(ctx, metadataKey, Metadata(l.Loggable()))
return child
}
merged := DeepMerge(existing, l.Loggable())
child := context.WithValue(ctx, metadataKey, merged)
return child
}
func MetadataFromContext(ctx context.Context) (Metadata, error) {
value := ctx.Value(metadataKey)
if value != nil {
metadata, ok := value.(Metadata)
if ok {
return metadata, nil
}
}
return nil, errors.New("context contains no metadata")
}
package log
import (
"testing"
"golang.org/x/net/context"
)
func TestContextContainsMetadata(t *testing.T) {
t.Parallel()
m := Metadata{"foo": "bar"}
ctx := ContextWithLoggable(context.Background(), m)
got, err := MetadataFromContext(ctx)
if err != nil {
t.Fatal(err)
}
_, exists := got["foo"]
if !exists {
t.Fail()
}
}
func TestContextWithPreexistingMetadata(t *testing.T) {
t.Parallel()
ctx := ContextWithLoggable(context.Background(), Metadata{"hello": "world"})
ctx = ContextWithLoggable(ctx, Metadata{"goodbye": "earth"})
got, err := MetadataFromContext(ctx)
if err != nil {
t.Fatal(err)
}
_, exists := got["hello"]
if !exists {
t.Fatal("original key not present")
}
_, exists = got["goodbye"]
if !exists {
t.Fatal("new key not present")
}
}
package log
type entry struct {
loggables []Loggable
system string
event string
}
package log
import "golang.org/x/net/context"
func ExampleEventLogger() {
{
log := EventLogger(nil)
e := log.EventBegin(context.Background(), "dial")
e.Done()
}
{
log := EventLogger(nil)
e := log.EventBegin(context.Background(), "dial")
_ = e.Close() // implements io.Closer for convenience
}
}
package log
import (
"encoding/json"
"fmt"
"time"
context "golang.org/x/net/context"
)
// StandardLogger provides API compatibility with standard printf loggers
// eg. go-logging
type StandardLogger 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{})
Panic(args ...interface{})
Panicf(format string, args ...interface{})
Warning(args ...interface{})
Warningf(format string, args ...interface{})
}
// EventLogger extends the StandardLogger interface to allow for log items
// containing structured metadata
type EventLogger interface {
StandardLogger
// Event merges structured data from the provided inputs into a single
// machine-readable log event.
//
// If the context contains metadata, a copy of this is used as the base
// metadata accumulator.
//
// If one or more loggable objects are provided, these are deep-merged into base blob.
//
// Next, the event name is added to the blob under the key "event". If
// the key "event" already exists, it will be over-written.
//
// Finally the timestamp and package name are added to the accumulator and
// the metadata is logged.
Event(ctx context.Context, event string, m ...Loggable)
EventBegin(ctx context.Context, event string, m ...Loggable) *EventInProgress
}
// Logger retrieves an event logger by name
func Logger(system string) EventLogger {
// 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)
if len(system) == 0 {
setuplog := getLogger("setup-logger")
setuplog.Warning("Missing name parameter")
system = "undefined"
}
logger := getLogger(system)
return &eventLogger{system: system, StandardLogger: logger}
}
// eventLogger implements the EventLogger and wraps a go-logging Logger
type eventLogger struct {
StandardLogger
system string
// TODO add log-level
}
func (el *eventLogger) EventBegin(ctx context.Context, event string, metadata ...Loggable) *EventInProgress {
start := time.Now()
el.Event(ctx, fmt.Sprintf("%sBegin", event), metadata...)
eip := &EventInProgress{}
eip.doneFunc = func(additional []Loggable) {
metadata = append(metadata, additional...) // anything added during the operation
metadata = append(metadata, LoggableMap(map[string]interface{}{ // finally, duration of event
"duration": time.Now().Sub(start),
}))
el.Event(ctx, event, metadata...)
}
return eip
}
func (el *eventLogger) Event(ctx context.Context, event string, metadata ...Loggable) {
// short circuit if theres nothing to write to
if !WriterGroup.Active() {
return
}
// Collect loggables for later logging
var loggables []Loggable
// get any existing metadata from the context
existing, err := MetadataFromContext(ctx)
if err != nil {
existing = Metadata{}
}
loggables = append(loggables, existing)
for _, datum := range metadata {
loggables = append(loggables, datum)
}
e := entry{
loggables: loggables,
system: el.system,
event: event,
}
accum := Metadata{}
for _, loggable := range e.loggables {
accum = DeepMerge(accum, loggable.Loggable())
}
// apply final attributes to reserved keys
// TODO accum["level"] = level
accum["event"] = e.event
accum["system"] = e.system
accum["time"] = FormatRFC3339(time.Now())
out, err := json.Marshal(accum)
if err != nil {
el.Errorf("ERROR FORMATTING EVENT ENTRY: %s", err)
return
}
WriterGroup.Write(append(out, '\n'))
}
type EventInProgress struct {
loggables []Loggable
doneFunc func([]Loggable)
}
// Append adds loggables to be included in the call to Done
func (eip *EventInProgress) Append(l Loggable) {
eip.loggables = append(eip.loggables, l)
}
// SetError includes the provided error
func (eip *EventInProgress) SetError(err error) {
eip.loggables = append(eip.loggables, LoggableMap{
"error": err.Error(),
})
}
// Done creates a new Event entry that includes the duration and appended
// loggables.
func (eip *EventInProgress) Done() {
eip.doneFunc(eip.loggables) // create final event with extra data
}
// Close is an alias for done
func (eip *EventInProgress) Close() error {
eip.Done()
return nil
}
func FormatRFC3339(t time.Time) string {
return t.UTC().Format(time.RFC3339Nano)
}
package log
// Loggable describes objects that can be marshalled into Metadata for logging
type Loggable interface {
Loggable() map[string]interface{}
}
type LoggableMap map[string]interface{}
func (l LoggableMap) Loggable() map[string]interface{} {
return l
}
// LoggableF converts a func into a Loggable
type LoggableF func() map[string]interface{}
func (l LoggableF) Loggable() map[string]interface{} {
return l()
}
func Deferred(key string, f func() string) Loggable {
function := func() map[string]interface{} {
return map[string]interface{}{
key: f(),
}
}
return LoggableF(function)
}
func Pair(key string, l Loggable) Loggable {
return LoggableMap{
key: l,
}
}
package log
import (
"encoding/json"
"errors"
"reflect"
"github.com/satori/go.uuid"
)
// Metadata is a convenience type for generic maps
type Metadata map[string]interface{}
// Uuid returns a Metadata with the string key and UUID value
func Uuid(key string) Metadata {
return Metadata{
key: uuid.NewV4().String(),
}
}
// DeepMerge merges the second Metadata parameter into the first.
// Nested Metadata are merged recursively. Primitives are over-written.
func DeepMerge(b, a Metadata) Metadata {
out := Metadata{}
for k, v := range b {
out[k] = v
}
for k, v := range a {
maybe, err := Metadatify(v)
if err != nil {
// if the new value is not meta. just overwrite the dest vaue
out[k] = v
continue
}
// it is meta. What about dest?
outv, exists := out[k]
if !exists {
// the new value is meta, but there's no dest value. just write it
out[k] = v
continue
}
outMetadataValue, err := Metadatify(outv)
if err != nil {
// the new value is meta and there's a dest value, but the dest
// value isn't meta. just overwrite
out[k] = v
continue
}
// both are meta. merge them.
out[k] = DeepMerge(outMetadataValue, maybe)
}
return out
}
// Loggable implements the Loggable interface
func (m Metadata) Loggable() map[string]interface{} {
// NB: method defined on value to avoid de-referencing nil Metadata
return m
}
func (m Metadata) JsonString() (string, error) {
// NB: method defined on value
b, err := json.Marshal(m)
return string(b), err
}
// Metadatify converts maps into Metadata
func Metadatify(i interface{}) (Metadata, error) {
value := reflect.ValueOf(i)
if value.Kind() == reflect.Map {
m := map[string]interface{}{}
for _, k := range value.MapKeys() {
m[k.String()] = value.MapIndex(k).Interface()
}
return Metadata(m), nil
}
return nil, errors.New("is not a map")
}
package log
import "testing"
func TestOverwrite(t *testing.T) {
t.Parallel()
under := Metadata{
"a": Metadata{
"b": Metadata{
"c": Metadata{
"d": "the original value",
"other": "SURVIVE",
},
},
},
}
over := Metadata{
"a": Metadata{
"b": Metadata{
"c": Metadata{
"d": "a new value",
},
},
},
}
out := DeepMerge(under, over)
dval := out["a"].(Metadata)["b"].(Metadata)["c"].(Metadata)["d"].(string)
if dval != "a new value" {
t.Fatal(dval)
}
surv := out["a"].(Metadata)["b"].(Metadata)["c"].(Metadata)["other"].(string)
if surv != "SURVIVE" {
t.Fatal(surv)
}
}
func TestMarshalJSON(t *testing.T) {
t.Parallel()
bs, _ := Metadata{"a": "b"}.JsonString()
t.Log(bs)
}
func TestMetadataIsLoggable(t *testing.T) {
t.Parallel()
func(l Loggable) {
}(Metadata{})
}
package log
import (
"errors"
"fmt"
"os"
logging "github.com/whyrusleeping/go-logging"
)
func init() {
SetupLogging()
}
var ansiGray = "\033[0;37m"
var ansiBlue = "\033[0;34m"
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}",
}
var defaultLogFormat = "color"
// Logging environment variables
const (
envLogging = "IPFS_LOGGING"
envLoggingFmt = "IPFS_LOGGING_FMT"
)
// ErrNoSuchLogger is returned when the util pkg is asked for a non existant logger
var ErrNoSuchLogger = errors.New("Error: No such logger")
// loggers is the set of loggers in the system
var loggers = map[string]*logging.Logger{}
// SetupLogging will initialize the logger backend and set the flags.
func SetupLogging() {
lfmt := LogFormats[os.Getenv(envLoggingFmt)]
if lfmt == "" {
lfmt = LogFormats[defaultLogFormat]
}
backend := logging.NewLogBackend(os.Stderr, "", 0)
logging.SetBackend(backend)
logging.SetFormatter(logging.MustStringFormatter(lfmt))
lvl := logging.ERROR
if logenv := os.Getenv(envLogging); logenv != "" {
var err error
lvl, err = logging.LogLevel(logenv)
if err != nil {
fmt.Println("error setting log levels", err)
}
}
SetAllLoggers(lvl)
}
// SetDebugLogging calls SetAllLoggers with logging.DEBUG
func SetDebugLogging() {
SetAllLoggers(logging.DEBUG)
}
// 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)
}
}
// SetLogLevel changes the log level of a specific subsystem
// name=="*" changes all subsystems
func SetLogLevel(name, level string) error {
lvl, err := logging.LogLevel(level)
if err != nil {
return err
}
// wildcard, change all
if name == "*" {
SetAllLoggers(lvl)
return nil
}
// Check if we have a logger by that name
if _, ok := loggers[name]; !ok {
return ErrNoSuchLogger
}
logging.SetLevel(lvl, name)
return nil
}
func getLogger(name string) *logging.Logger {
log := logging.MustGetLogger(name)
log.ExtraCalldepth = 1
loggers[name] = log
return log
}
package log
import (
"io"
logging "github.com/whyrusleeping/go-logging"
)
// Global writer group for logs to output to
var WriterGroup = NewMirrorWriter()
type Option func()
// Configure applies the provided options sequentially from left to right
func Configure(options ...Option) {
for _, f := range options {
f()
}
}
// LdJSONFormatter Option formats the event log as line-delimited JSON
var LdJSONFormatter = func() {
logging.SetFormatter(&PoliteJSONFormatter{})
}
// TextFormatter Option formats the event log as human-readable plain-text
var TextFormatter = func() {
logging.SetFormatter(logging.DefaultFormatter)
}
func Output(w io.Writer) Option {
return func() {
backend := logging.NewLogBackend(w, "", 0)
logging.SetBackend(backend)
// TODO return previous Output option
}
}
// LevelDebug Option sets the log level to debug
var LevelDebug = func() {
logging.SetLevel(logging.DEBUG, "")
}
// LevelError Option sets the log level to error
var LevelError = func() {
logging.SetLevel(logging.ERROR, "")
}
// LevelInfo Option sets the log level to info
var LevelInfo = func() {
logging.SetLevel(logging.INFO, "")
}
{
"name": "go-log",
"version": "1.0.0",
"language": "go",
"go":{
"dvcsimport":"github.com/ipfs/go-log"
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment