Documentation ¶
Overview ¶
Package util contains common functionality which is required by a typical server side any GO application. Namely it contains functionality to read JSON configuration file (from ilyakaznacheev) and rotating logging functionality (from lumberjack). Essentially these are few simple useful wrappers convenient for any GO application.
If user passes a configuration file with absolute path, it is read as is. Otherwise environment variable GO_CFG_HOME is checked to see if contains the directory name in which the passed configuration file is checked. If found, it is read and configuration structure is returned.
The built-in conditional variable in Go - sync.Cond - broadcasts or signal the waiting go routine exactly once. If the waiting routine misses that, it waits infinitely and essentially your program hangs. There is a long running argument within the Go Community whether the conditional variable to be abolished altogether or not: https://github.com/golang/go/issues/21165 Many within the Go Community want to abolish it altogether while the few other experienced professionals want to keep it and improve it. The proposers want to go all hog on Go channels. No doubt Channels is the marquee feature of the Go Language. I do not know whether the cost of 'channels' is all justified for the ubiquitous usage of Channel in Go applications. Coming from C and Java Programming background, all I want is working sync.Cond. What I have seen though, if Signal or Broadcast message is missed; my program is toast. Now Go Community may want to claim that they only entertain flawless coders so that a programmer knows exactly when to expect the 'signal'. In my unit tests when tasks finish very early only, I have seen that the cost of acquiring Lock is significant; meaning the waiting Go routine misses the Signal before starting to Wait. Hence the humble attempt - try multiple Broadcast so the listeners get more than one opportunity to get out of Wait loop. I agree, it is a weak solution. But it is helping in my use case where I want 'channels usage strictly managed'.
The usage pattern is at any given time, all waits will be considered for a single condition only. We are trying to solve the problem of at least one 'wait' coming after the Broadcast. So repeat call on the Broadcast are not allowed until the first Broadcast is complete which is determined based on how many receipts we get from waiters.
In cases where we are not concerned about whether all waiters respond back but at least one 'waiter' at least responds back. The use case is we want any one to pick up the resume the work upon completing of the work. It is essentially Broadcast with argument 1, which is simplified as Signal() call.
CondVar bundles required locker with it so as you do not need to do explicit Lock and Unlock invocation around Wait.
There are three methods to initialize logs and set log settings:
1) Caller can pass LoggingCfg structure as defined here to initialize logs.
2) Alternatively, assuming caller has used 'cfg' program in the 'util' package, that 'uber' configuration file can be passed as long as it has a JSON member of name "LogSettings". The configuration file can be passed: - either with the absolute path - or the file name only in which case GP_CFG_HOME environment variable value is used as the directory name where the give configuration file is located.
3) Finally, caller can explicitly call InitializeLog method with arguments. The file path can be absolute. It is not absolute, it is appended to the current working directory.
Until LoggingCfg is set, GlobalLogSettings will be nil. All log calls will be handled by the built in logging facility of Golang. Once the logging is initialized by one of the above mentioned 3 methods; log calls will be directing the output to the specified rotating log file.
Index ¶
- Constants
- func Absint(x int) int
- func ExtractCfgJsonEleFromBytes(byteValue []byte, cfgJsonElementName string) ([]byte, error)
- func ExtractCfgJsonEleFromFile(fileName string, cfgJsonElementName string) ([]byte, error)
- func Gcd(a, b int) int
- func GcdList(nums []int) int
- func GetCfgHomeDir() (string, error)
- func InitializeLog(fn string, ms int, bk int, age int, compress bool)
- func IsLoggingConfigured() bool
- func Lcm(a, b int) int
- func LcmList(nums []int) int
- func Log(msg string)
- func LogDebug(msg string)
- func ReadCfg(cfg interface{}, fileName string) error
- func SetConsoleLog(val bool)
- func SetDebugLog(val bool)
- func SetLogSettings(cfgFileName string)
- func SetLoggingCfg(ls *LoggingCfg)
- type Blob
- type CondVar
- type ConfigHome
- type LoggingCfg
- type Monitor
- type Monitored
- type Stack
Constants ¶
const LoggingCfgJsonElementName = "LogSettings"
Name of the Json element in any Json Configuration file which contains LoggingCfg structure value.
Variables ¶
This section is empty.
Functions ¶
func ExtractCfgJsonEleFromBytes ¶
Returns the byte array corresponding to json segment of the specified config element in the passed byte array. Second argument is the name of the configuration structure member caller is seeking.
func ExtractCfgJsonEleFromFile ¶
Returns the byte array corresponding to json segment of specified config element in the passed filename. If file name is with the absolute path, reading is attempted for that location, else the given file name is looked up in to the directory as pointed by GO_CFG_HOME. Second argument is the name of the configuration structure member caller is seeking.
func Gcd ¶ added in v0.0.4
Gcd calculates the greatest common divisor using the Euclidean algorithm.
func GcdList ¶ added in v0.0.4
GcdList calculates the greatest common divisor of a list of integers.
func GetCfgHomeDir ¶
Returns directory which holds config files.
func InitializeLog ¶
Initialize logging to given inputs: fn : Log files with fill path ms : Maximum allowed log file size in Megabytes bk : How many backups to be retained. age : Past logs of how many days to be retained. compress: Whether logs are compressed or not.
func IsLoggingConfigured ¶
func IsLoggingConfigured() bool
Indicates whether logging has been configured or not.
func LogDebug ¶
func LogDebug(msg string)
Log debug messages. Invocation of this call will result in adding the message to the log provided SetDebugLog(true) is called.
func SetLogSettings ¶
func SetLogSettings(cfgFileName string)
It assumes argument configuration file in JSON format and it contains an element named LogSettings. Contents of that member are used to build the log setting configuration.
func SetLoggingCfg ¶
func SetLoggingCfg(ls *LoggingCfg)
Types ¶
type Blob ¶ added in v0.0.4
type Blob struct {
Data []byte
}
Data returned by GetData method, Health Status Data Typically it should be Json string byte array.
type CondVar ¶ added in v0.0.4
Wrapper around the built-in Cond struct. All additional variables are for internal consumption only.
func NewCondVar ¶ added in v0.0.4
Create CondVar where the first argument is the gap between two subsequent broadcasts in microseconds. The second argument indicates how long to keep broadcasting, duration again in microseconds.
func (*CondVar) Broadcast ¶ added in v0.0.4
Broadcast with how many 'receipts' from waiters are expected.
type ConfigHome ¶
type ConfigHome struct {
Dir string `env:"GO_CFG_HOME" env-description:"Directory where we can find configuration file"`
}
type LoggingCfg ¶
type LoggingCfg struct { LogFileName string MaxSizeInMb int Backups int AgeInDays int Compress bool LogOnConsole bool DebugLog bool }
var GlobalLogSettings *LoggingCfg
Pointer to a structure which holds log settings in effect.
func FormLoggingCfg ¶
func FormLoggingCfg(ls []byte) (*LoggingCfg, error)
Make logging configuration struct from the given input string.
type Monitor ¶ added in v0.0.4
type Monitor struct { MonDataChan chan Blob // exposed so anyone interested in Data can get handle // contains filtered or unexported fields }
Monitors the specified entity by invoking it's GetData at given frequency. For now it only Logs the Data.
func NewMonitor ¶ added in v0.0.4
Builds a new monitor for the given entity. GetData method on that entity will be invoked at the given frequency. Error is thrown when the entity is nil. There is no validation on the frequency number right now, it is Seconds.
type Monitored ¶ added in v0.0.4
type Monitored interface { GetData() Blob // Reference name, presumably unique so it is easier to locate in Logs Name() string }
The entity or service which we want to monitor. That entity should implement this interface. Implementation of this method should be 'lightweight' it is to be invoked at the higher frequency.