-
Notifications
You must be signed in to change notification settings - Fork 344
Logging for preliminary review #421
Logging for preliminary review #421
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a lot to absorb here, but this is great work.
// the use of any assumptions while starting Eris-DB | ||
if do.WorkDir == "" { | ||
if currentDirectory, err := os.Getwd(); err != nil { | ||
panic(fmt.Sprintf("No directory provided and failed to get current "+ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we don't need to panic here, if we cleanly os.Exit(1)
below ?
err = serverProcess.Start() | ||
|
||
newCore, err := NewCoreFromDo(do) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
redundant whiteline
|
||
// Safely get the subtree from a viper config, returning an error if it could not | ||
// be obtained for any reason. | ||
func ViperSubConfig(conf *viper.Viper, configSubtreePath string) (subConfig *viper.Viper, err error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sweet!
logger logrus.Logger | ||
} | ||
|
||
var _ kitlog.Logger = (*logrusLogger)(nil) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
:)
) | ||
|
||
func Capture(stdLibLogger log.Logger, | ||
logger loggers.InfoTraceLogger) io.Writer { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
indentation
package loggers | ||
|
||
import ( | ||
"github.com/eapache/channels" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we should maybe try to import from the "official" (does such a thing exist ?) golang repository where possible?
import "gopkg.in/eapache/channels.v1"
// context: [log call site (5), Info/Trace (4), MultipleChannelLogger.Log (3), | ||
// kitlog.Context.Log (2), kitlog.bindValues (1) (binding occurs), | ||
// kitlog.Caller (0), stack.caller] | ||
infoTraceLoggerCallDepth = 5 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah, about that... :) - it's ok though, we have a specific logging situation and the proposed solution is, albeit complete, but elegant
vm "github.com/eris-ltd/eris-db/manager/eris-mint/evm" | ||
"github.com/eris-ltd/eris-db/manager/eris-mint/state" | ||
state_types "github.com/eris-ltd/eris-db/manager/eris-mint/state/types" | ||
manager_types "github.com/eris-ltd/eris-db/manager/types" | ||
rpc_tm_types "github.com/eris-ltd/eris-db/rpc/tendermint/core/types" | ||
"github.com/eris-ltd/eris-db/txs" | ||
log "github.com/eris-ltd/eris-logger" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do we still need eris-logger?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
noop
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it definitely needs to go else cli gets a build error when importing edb
"chainId", startedState.ChainID, | ||
"lastBlockHeight", startedState.LastBlockHeight, | ||
"lastBlockHash", startedState.LastBlockHash, | ||
structure.MessageKey, "Loaded state") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
where is stMessageKey
defined / imported ?
@@ -12,14 +12,14 @@ import ( | |||
ptypes "github.com/eris-ltd/eris-db/permission/types" | |||
"github.com/eris-ltd/eris-db/txs" | |||
|
|||
. "github.com/tendermint/go-common" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
rejoyce
LGTM |
Logging for preliminary review
This WIP PR included the framework of the logging system I have written so far to implement ideas from #421. It also includes some changes that seemed apt to make as I introduce a non-global logger at the root level.
Guide to changes:
Housekeeping
do *definition.Do
and loggers) into functional dependencies:Logging
InfoTraceLogger
as the main binary interface (choose just one level/channel) for our logging. Each channel can be routed separatelyChannelLogger
to have a non-blocking non-overflowing never-stop-the-caller executionMultipleChannelLogger
andMultipleOutputLogger
allowing composing of loggers roughly under 'OR' / 'AND' logic respectively. These will will allow for setting up arbitrary numbers of logging sinks (remote servers, syslog, stderr, files, etc).go-kit log and log15
After various drafts of logging and flip-flopping between just using log15's interface as our main interface and wrapping it and just go-kit log I have opted for something of a mash-up between go-kit log and log15. Although I would argue (having read up quite a bit on the design intentions of go-kit log) that I am using go-kit log as intended: in that it is designed to be wrapped and composed. In some ways you might see go-kit log as a logging facade rather like slf4j (in Java land), but simpler.
go-kit is a thematically related collection of packages designed for 'microservice architectures'. You don't have to care about that in order for it to be relevant. But it is based around a generic structured logging interface
Log (keyvals... interface{}) error
. This is very similar to log15's handler, but by making it the single interface everything is built around it encourages logging to behave has a composable pipeline with a somewhat flexible, but structured, schema, that you can wrap for consumption (which is whatInfoTraceLogger
does). They also modelContext
as a struct that wraps a logger rather than a field within aRecord
as log15 does. This means that contexts are established external to loggers/records and that there are no 'preferred fields'.My feeling is that this suits how we should come to think about logs: as data in their own right that drives other things. I also think that this kind of machinery might be a better way to think about events in general, though it needn't be.
I was also keen not to have too many log levels, because I think they rely on that a shared hierarchy exists between the mind of the log line emitter and the mind of log line consumer that does not generally exist. I also think that
Critical
,Error
, andFatal
are somewhat misnomers: in that if you are logging something then by definition you have handled any error (this might be appropriate in other settings, but for us as a fault tolerant system I think most things should not be fatal). However it does seem useful to have a 'noisy' and a 'quiet' channel for logs, which I have designated as 'Trace' and 'Info' respectively. I prefer 'trace' from 'debug' because I like that it doesn't try to suggest the noisy log channel is only good for debugging, in fact it might be used to drive other systems. It would have be hard to wrap log15 to provide this interface.However, since log15 has lots of nice handlers and since Tendermint uses log15 (their very slightly different fork) I have written an adapter that allows us to capture log15 logging and also allows use to use log15 handlers. I think this kind of wrapping is in the spirit of go-kit log, but wouldn't really be the other way around.