Documentation
¶
Overview ¶
Package govec is a vector clock logging library
Index ¶
- Variables
- func NewNopCore() zapcore.Core
- type GoLog
- func (gv *GoLog) DisableBufferedWrites() (err error)
- func (gv *GoLog) EnableBufferedWrites() (err error)
- func (gv *GoLog) Flush() bool
- func (gv *GoLog) GetCurrentVC() vclock.VClock
- func (gv *GoLog) InitGoVector(processid string, config GoLogConfig, logfilenames ...string)
- func (gv *GoLog) LogLocalEvent(mesg string, opts GoLogOptions) (logSuccess bool)
- func (gv *GoLog) LogLocalEventZap(level zapcore.Level, msg string, fields ...zap.Field)
- func (gv *GoLog) Named(s string) *GoLog
- func (gv *GoLog) PrepareSend(mesg string, buf interface{}, opts GoLogOptions) (encodedBytes []byte)
- func (gv *GoLog) PrepareSendZap(mesg string, level zapcore.Level, fields ...zap.Field) (encodedBytes []byte)
- func (gv *GoLog) PrepareSendZapWrapPayload(mesg string, buf interface{}, level zapcore.Level, fields ...zap.Field) (encodedBytes []byte)
- func (gv *GoLog) StartBroadcast(mesg string, opts GoLogOptions)
- func (gv *GoLog) StopBroadcast()
- func (gv *GoLog) UnpackReceive(mesg string, buf []byte, unpack interface{}, opts GoLogOptions)
- func (gv *GoLog) UnpackReceiveZap(mesg string, buf []byte, level zapcore.Level, fields ...zap.Field)
- func (gv *GoLog) UnpackReceiveZapWrapPayload(mesg string, buf []byte, unpack interface{}, level zapcore.Level, ...)
- func (gv *GoLog) With(fields ...zap.Field) *GoLog
- func (gv *GoLog) WithLazy(fields ...zap.Field) *GoLog
- func (gv *GoLog) WithOptions(opts ...zap.Option) *GoLog
- func (gv *GoLog) WrapBaseZapLogger(baseLogger *zap.Logger, opts ...zap.Option) *zap.Logger
- type GoLogConfig
- type GoLogCore
- type GoLogOptions
- type GoLogWriteSyncer
- type ZapEntryInput
- type ZapLogInput
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var ( // LogToTerminal controls whether internal GoLog debugging statements are printed to stdout. False by default LogToTerminal = false )
Functions ¶
func NewNopCore ¶
NewNopCore returns a no-op Core. Copy of zap's but enable returns true instead of false
Types ¶
type GoLog ¶
type GoLog struct {
// Embedded Zap logger to pass all logs to
*zap.Logger
// Cached loggers derived from the embedded Zap logger.
// Wrapped loggers are used to skip different levels of the stacktrace so only user
// code appears in the stacktrace
SugaredLogger *zap.SugaredLogger
// contains filtered or unexported fields
}
GoLog struct provides an interface to creating and maintaining vector timestamp entries in the generated log file. GoLogs are initialized with Configs which control logger output, format, and frequency.
Example (Basic) ¶
Basic example of GoVectors key functions
package main
import (
"fmt"
"github.com/jmcmenamy/GoVector/govec"
)
func main() {
//Initialize logger with default configuration. This can be done in
//a var block to ensure that GoVector is initialized at boot time.
Logger := govec.InitGoVector("MyProcess", "LogFile", govec.GetDefaultRegexConfig())
opts := govec.GetDefaultLogOptions()
//An example message
messagepayload := []byte("samplepayload")
//Prior to sending a message, call PrepareSend on the payload to
//encode the payload and append this processes vector clock to the
//payload
encodedVCpayload := Logger.PrepareSend("Sending Message", messagepayload, opts)
//encodedVCpayload is ready to be written to the network
//ex) conn.Write(encodedVCpayload)
//Receiving Example
//First allocate a buffer to receive a message into. This must be
//the same type as the encoded message. Here incommingMessage and
//messagepayload are the same type []byte.
var incommingMessage []byte
//Prior to unpacking call a message must be received
//ex) conn.Read(encodedVCPayload)
//Call UnpackReceive on received messages to update local vector
//clock values, and decode the original message.
Logger.UnpackReceive("Received Message from server", encodedVCpayload, &incommingMessage, opts)
fmt.Printf("Received Message: %s\n", incommingMessage)
//Important local events can be timestamped with vector clocks
//using LogLocalEvent, which also increments the local clock.
Logger.LogLocalEvent("Example Complete", opts)
}
Output: Received Message: samplepayload
Example (DisVizCompatible) ¶
GoVector logs can produce JSON logs for visualization with DisViz
package main
import (
"fmt"
"github.com/jmcmenamy/GoVector/govec"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
)
func main() {
//Initialize logger with default zap configuration. This can be done in
//a var block to ensure that GoVector is initialized at boot time.
Logger := govec.InitGoVector("MyProcess", "LogFile", govec.GetDefaultZapConfig())
//An example message
messagepayload := []byte("samplepayload")
//Prior to sending a message, call PrepareSendZapWrapPayload on the payload to
//encode the payload and append this processes vector clock to the
//payload. This will wrap messagepayload inside encodedVCpayload
encodedVCpayload := Logger.PrepareSendZapWrapPayload("Sending Message", messagepayload, zapcore.InfoLevel, zap.Int("messageNum", 1))
//encodedVCpayload is ready to be written to the network
//ex) conn.Write(encodedVCpayload)
//Receiving Example
//First allocate a buffer to receive a message into. This must be
//the same type as the encoded message. Here incommingMessage and
//messagepayload are the same type []byte.
var incommingMessage []byte
//Prior to unpacking call a message must be received
//ex) conn.Read(encodedVCPayload)
//Call UnpackReceiveZapWrapPayload on received messages to update local vector
//clock values, and decode the original message.
Logger.UnpackReceiveZapWrapPayload("Received Message from server", encodedVCpayload, &incommingMessage, zapcore.InfoLevel)
fmt.Printf("Received Message: %s\n", incommingMessage)
//Important local events can be timestamped with vector clocks
//using LogLocalEvent, which also increments the local clock.
Logger.LogLocalEventZap(zapcore.InfoLevel, "Example Complete")
//The Zap API is also embedded in the GoLog object, so all Zap methods can also be called
Logger.Info("Example Complete", zap.Bool("boolField", false))
//Instead of wrapping the user payload inside the GoLog payload,
//PrepareSendZap/UnpackReceiveZap can be used to put the GoLog payload inside the user payload
//that is sent over the network.
type samplePayload struct {
encodedVCPayload []byte
}
payloadToSend := samplePayload{
encodedVCPayload: Logger.PrepareSendZap("Sending Message", zapcore.InfoLevel, zap.String("stringField", "value")),
}
//payloadToSend is ready to be encoded, written to the network, then decoded by another device.
//Then, we can grab the GoLog payload out of the decoded user payload.
Logger.UnpackReceiveZap("Received Message from server", payloadToSend.encodedVCPayload, zapcore.InfoLevel)
}
Output: Received Message: samplepayload
Example (Priority) ¶
Logging with priority trims all events which are lower from the specified priority from the log. This functionality is useful for isolating behaviour such as recovery protocols, from common behaviour like heartbeats.
package main
import (
"github.com/jmcmenamy/GoVector/govec"
"go.uber.org/zap/zapcore"
)
func main() {
//Access GoVectors default configureation, and set priority
config := govec.GetDefaultRegexConfig()
config.Level = zapcore.DebugLevel
config.PrintOnScreen = true
//Initialize GoVector
Logger := govec.InitGoVector("MyProcess", "PrioritisedLogFile", config)
opts := govec.GetDefaultLogOptions()
Logger.LogLocalEvent("Debug Priority Event", opts.SetPriority(zapcore.DebugLevel))
Logger.LogLocalEvent("Info Priority Event", opts.SetPriority(zapcore.InfoLevel))
Logger.LogLocalEvent("Warning Priority Event", opts.SetPriority(zapcore.WarnLevel))
Logger.LogLocalEvent("Error Priority Event", opts.SetPriority(zapcore.ErrorLevel))
Logger.LogLocalEvent("Fatal Priority Event", opts.SetPriority(zapcore.FatalLevel))
//BUG Output contains timestamps so it cant be tested with *******
//comments
//Debug Priority Event
//Info Priority Event
//Warning Priority Event
//Error Priority Event
//Fatal Priority Event
}
Example (TSVizCompatable) ¶
GoVector logs can be used to associate real time events for visualization with TSViz
package main
import (
"fmt"
"github.com/jmcmenamy/GoVector/govec"
)
func main() {
//Access config and set timestamps (realtime) to true
config := govec.GetDefaultRegexConfig()
config.UseTimestamps = true
//Initalize GoVector
Logger := govec.InitGoVector("MyProcess", "LogFile", config)
opts := govec.GetDefaultLogOptions()
//In Sending Process
//Prepare a Message
messagepayload := []byte("samplepayload")
finalsend := Logger.PrepareSend("Sending Message", messagepayload, opts)
//In Receiving Process
//receive message
var incommingMessage []byte
Logger.UnpackReceive("Received Message from server", finalsend, &incommingMessage, opts)
fmt.Printf("Received Message: %s\n", incommingMessage)
//Can be called at any point
Logger.LogLocalEvent("Example Complete", opts)
}
Output: Received Message: samplepayload
func InitGoVector ¶
func InitGoVector(processid string, logfilename string, config GoLogConfig) *GoLog
InitGoVector returns a GoLog which generates a logs prefixed with processid, to files with names logfilenames, appended with a -Log.txt or -zap-Log.txt. Any old log with the same name will be truncated for non-zap logs. zap logs will be parsed and used to initialize the vector clock Config controls logging options. See GoLogConfig for more details.
func UninitializedGoVector ¶
func UninitializedGoVector() *GoLog
Creates an Uninitialized GoLog that can still be logged to with zap logs Logs are buffered and will be logged immediately once this logger is initialized and output paths are given
func (*GoLog) DisableBufferedWrites ¶
DisableBufferedWrites disables buffered writes to the log file. All the log messages from now on will be written to the Log file immediately. Writes all the existing log messages that haven't been written to Log file yet.
func (*GoLog) EnableBufferedWrites ¶
EnableBufferedWrites enables buffered writes to the log file. All the log messages are only written to the LogFile via an explicit call to the function Flush. Note: Buffered writes are automatically disabled.
func (*GoLog) Flush ¶
Flush writes the log messages stored in the buffer to the Log File. This function should be used by the application to also force writes in the case of interrupts and crashes. Note: Calling Flush when BufferedWrites is disabled is essentially a no-op. Only to be used for regex style logging; no op for zap style logging
func (*GoLog) GetCurrentVC ¶
GetCurrentVC returns the current vector clock
func (*GoLog) InitGoVector ¶
func (gv *GoLog) InitGoVector(processid string, config GoLogConfig, logfilenames ...string)
InitGoVector returns a GoLog which generates a logs prefixed with processid, to files with names logfilenames, appended with a -Log.txt or -zap-Log.txt. Any old log with the same name will be truncated for non-zap logs. zap logs will be parsed and used to initialize the vector clock Config controls logging options. See GoLogConfig for more details.
func (*GoLog) LogLocalEvent ¶
func (gv *GoLog) LogLocalEvent(mesg string, opts GoLogOptions) (logSuccess bool)
LogLocalEvent implements LogLocalEvent with priority levels. If the priority of the logger is lower than or equal to the priority of this event then the current vector timestamp is incremented and the message is logged it into the Log File. A color coded string is also printed on the console. * LogMessage (string) : Message to be logged * Priority (LogPriority) : Priority at which the message is to be logged
func (*GoLog) LogLocalEventZap ¶
Ticks the clock and logs the given msg and fields and level level If the zap logger isn't initialized yet, store the entry for logging later
func (*GoLog) Named ¶
Named adds a new path segment to the logger's name. Segments are joined by periods. By default, Loggers are unnamed.
func (*GoLog) PrepareSend ¶
func (gv *GoLog) PrepareSend(mesg string, buf interface{}, opts GoLogOptions) (encodedBytes []byte)
PrepareSend is meant to be used immediately before sending. mesg will be logged buf is encode-able data (structure or basic type) Returned is an encoded byte array with logging information. This function is meant to be called before sending a packet. It updates the Vector Clock for its own process, packages with the clock using gob support and returns the new byte array that should be sent onwards over the network
func (*GoLog) PrepareSendZap ¶
func (gv *GoLog) PrepareSendZap(mesg string, level zapcore.Level, fields ...zap.Field) (encodedBytes []byte)
PrepareSendZap is meant to be used immediately before sending. mesg will be logged Returned is an encoded byte array with logging information. This function is meant to be called before sending a packet. It updates the Vector Clock for its own process, and returns the byte array that should be placed in the payload sent over the network.
func (*GoLog) PrepareSendZapWrapPayload ¶
func (gv *GoLog) PrepareSendZapWrapPayload(mesg string, buf interface{}, level zapcore.Level, fields ...zap.Field) (encodedBytes []byte)
PrepareSendZapWrapPayload is meant to be used immediately before sending. mesg will be logged buf is encode-able data (structure or basic type) buf is encoded inside of encodedBytes Returned is an encoded byte array with logging information. This function is meant to be called before sending a packet. It updates the Vector Clock for its own process, packages buf with the clock using gob support and returns the new byte array that should be sent onwards over the network.
func (*GoLog) StartBroadcast ¶
func (gv *GoLog) StartBroadcast(mesg string, opts GoLogOptions)
StartBroadcast allows to use vector clocks in the context of casual broadcasts sent via RPC. Any call to StartBroadcast must have a corresponding call to StopBroadcast, otherwise a deadlock will occur. All RPC calls made in-between the calls to StartBroadcast and StopBroadcast will be logged as a single event, will be sent out with the same vector clock and will represent broadcast messages from the current process to the process pool.
func (*GoLog) StopBroadcast ¶
func (gv *GoLog) StopBroadcast()
StopBroadcast is called once all RPC calls of a message broadcast have been sent.
func (*GoLog) UnpackReceive ¶
func (gv *GoLog) UnpackReceive(mesg string, buf []byte, unpack interface{}, opts GoLogOptions)
UnpackReceive is used to unmarshall network data into local structures. mesg will be logged the vector clock of this process will be merged with the vector clock received in the payload buf is the network data, previously packaged by PrepareSend. unpack is a pointer to a structure, the same as was packed by PrepareSend. This function is meant to be called immediately after receiving a packet. It unpacks the data by the program, the vector clock. It updates vector clock and logs it. and returns the user data
func (*GoLog) UnpackReceiveZap ¶
func (gv *GoLog) UnpackReceiveZap(mesg string, buf []byte, level zapcore.Level, fields ...zap.Field)
UnpackReceiveZap is used to unmarshall network data into local structures. mesg will be logged the vector clock of this process will be merged with the vector clock received in the payload buf is the network data, previously packaged by PrepareSendZap. unpack is a pointer to a structure, the same as was packed by PrepareSendZap. This function is meant to be called immediately after receiving a packet. It unpacks the data by the program, the vector clock. It updates vector clock and logs it. and returns the user data
func (*GoLog) UnpackReceiveZapWrapPayload ¶
func (gv *GoLog) UnpackReceiveZapWrapPayload(mesg string, buf []byte, unpack interface{}, level zapcore.Level, fields ...zap.Field)
UnpackReceiveZapWrapPayload is used to unmarshall network data into local structures. mesg will be logged the vector clock of this process will be merged with the vector clock received in the payload buf is the network data, previously packaged by PrepareSendZapWrapPayload. unpack is a pointer to a structure, the same as was packed by PrepareSendZapWrapPayload. This function is meant to be called immediately after receiving a packet. It unpacks the data by the program, the vector clock. It updates vector clock and logs it. and returns the user data
func (*GoLog) With ¶
With creates a child logger and adds structured context to it. Fields added to the child don't affect the parent, and vice versa. Any fields that require evaluation (such as Objects) are evaluated upon invocation of With.
func (*GoLog) WithLazy ¶
WithLazy creates a child logger and adds structured context to it lazily.
The fields are evaluated only if the logger is further chained with [With] or is written to with any of the log level methods. Until that occurs, the logger may retain references to objects inside the fields, and logging will reflect the state of an object at the time of logging, not the time of WithLazy().
WithLazy provides a worthwhile performance optimization for contextual loggers when the likelihood of using the child logger is low, such as error paths and rarely taken branches.
Similar to [With], fields added to the child don't affect the parent, and vice versa.
func (*GoLog) WithOptions ¶
WithOptions clones the current Logger, applies the supplied Options, and returns the resulting Logger. It's safe to use concurrently.
func (*GoLog) WrapBaseZapLogger ¶
Given an existing zap Logger, return a new zap logger that will keep the same configuration, but also write any logs to this GoLog logger the level of the core of this logger will be the level of gv
type GoLogConfig ¶
type GoLogConfig struct {
// Buffered denotes if the logging events are buffered until flushed. This option
// increase logging performance at the cost of safety.
Buffered bool
// PrintOnScreen denotes if logging events are printed to screen.
PrintOnScreen bool
// AppendLog determines to continue writing to a log from a prior execution.
AppendLog bool
// UseTimestamps determines to log real time timestamps for TSVis
UseTimestamps bool
// EncodingStrategy for customizable interoperability
EncodingStrategy func(interface{}) ([]byte, error)
// DecodingStrategy for customizable interoperability
DecodingStrategy func([]byte, interface{}) error
// LogToFile determines to write logging events to a file
LogToFile bool
// Level determines the minimum priority event to log
Level zapcore.Level
// AddCaller determines to add caller information to each log. For Zap logs only.
AddCaller bool
// AddStacktrace determines to add the stacktrace to each log. For Zap logs only.
AddStacktrace bool
// When buffering, the maximum amount of data the writer will buffer before flushing
Size int
// When buffering, how often the writer should flush data if there have been no writes. 0 if only manual Syncing
Interval time.Duration
// InitialVC is the initial vector clock value, nil by default
InitialVC vclock.VClock
// Whether or not to generate logs with zap, which supports arbitrary key value pairs
GenerateZapLogs bool
// Whether or not to generate logs using regex style, compatible with the original Shiviz
GenerateRegexLogs bool
// Prefix to add to zap log paths for where to write files. Empty is fine
ZapLogPrefix string
}
GoLogConfig controls the logging parameters of GoLog and is taken as input to GoLog initialization. See defaults in GetDefaultZapConfig or GetDefaultRegexConfig.
func GetDefaultRegexConfig ¶
func GetDefaultRegexConfig() GoLogConfig
GetDefaultRegexConfig returns the default GoLogConfig with default values for various fields.
func GetDefaultZapConfig ¶
func GetDefaultZapConfig() GoLogConfig
GetDefaultZapConfig returns the default GoLogConfig with default values for various fields when generating logs with Zap
type GoLogCore ¶
GoLogCore wraps an existing zapcore.Core and intercepts writes, to add a pid and vector clock to every log entry
func (*GoLogCore) Check ¶
func (c *GoLogCore) Check(ent zapcore.Entry, ce *zapcore.CheckedEntry) *zapcore.CheckedEntry
Have to overwrite method and copy implementation so our GoLogZapCore receiver is used instead of zapcore.ioCore when adding a core to a checkedEntry Check determines whether the supplied Entry should be logged (using the embedded LevelEnabler and possibly some extra logic). If the entry should be logged, the Core adds itself to the CheckedEntry and returns the result.
Callers must use Check before calling Write.
func (*GoLogCore) With ¶
With adds structured context to the Core. Return copy of this core where fields will be added to every log to the GoLog and the base logger
func (*GoLogCore) Write ¶
Write entry with fields to this core, and pass write through to base wrapped core Write serializes the Entry and any Fields supplied at the log site and writes them to their destination.
If called, Write should always log the Entry and Fields; it should not replicate the logic of Check.
type GoLogOptions ¶
GoLogOptions provides logging parameters for individual logging statements. Used in Regex logs only.
func GetDefaultLogOptions ¶
func GetDefaultLogOptions() GoLogOptions
GetDefaultLogOptions returns the default GoLogOptions with default values for the fields
func (*GoLogOptions) SetPriority ¶
func (o *GoLogOptions) SetPriority(Priority zapcore.Level) GoLogOptions
SetPriority returns a new GoLogOptions object with its priority field set to Priority. Follows the builder pattern. Priority : (GoLogPriority) The Priority that the new GoLogOptions object must have
type GoLogWriteSyncer ¶
type GoLogWriteSyncer struct {
// contains filtered or unexported fields
}
GoLogWriteSyncer lets you flip between an unbuffered and a buffered write syncer.
func NewGoLogWriteSyncer ¶
func NewGoLogWriteSyncer(unbuf zapcore.WriteSyncer) *GoLogWriteSyncer
Create a new GoLogWriteSyncer, which eventually writes to unbuf. Initially unbuffered
func (*GoLogWriteSyncer) DisableBuffering ¶
func (s *GoLogWriteSyncer) DisableBuffering() (err error)
DisableBuffering switches back to the unbuffered writer Syncs any data in the existing buf
func (*GoLogWriteSyncer) EnableBuffering ¶
func (s *GoLogWriteSyncer) EnableBuffering(size int, interval time.Duration) error
EnableBuffering switches over to the buffered writer size is the maximum amount of data the writer will buffered before flushing. interval is how often the writer should flush data if there have been no writes. 0 if only manual Syncing
func (*GoLogWriteSyncer) Sync ¶
func (s *GoLogWriteSyncer) Sync() error
Sync calls the Sync method of the currently active Zap WriteSyncer
type ZapEntryInput ¶
type ZapEntryInput struct {
// contains filtered or unexported fields
}
Represents an entry that we log later, once the zap logger is initialized
type ZapLogInput ¶
type ZapLogInput struct {
// contains filtered or unexported fields
}
Represents a log that we try to log later, once the zap logger is initialized