Skip to content

Commit

Permalink
Merge pull request techrail#76 from itishrishikesh/hp_docs
Browse files Browse the repository at this point in the history
doc comments for client
  • Loading branch information
vaibhav-kaushal authored Oct 15, 2023
2 parents bc854b4 + 44c137d commit dc4352f
Show file tree
Hide file tree
Showing 7 changed files with 89 additions and 120 deletions.
14 changes: 11 additions & 3 deletions client/barkslogger.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Package barkslogger manages everything related slog handler that's to be used by bark client.
// This file manages everything related slog handler that's to be used by bark client.
package client

import (
Expand All @@ -7,7 +7,6 @@ import (
"io"
"log"
"log/slog"
"os"
)

// Constants for custom log levels in bark.
Expand All @@ -26,14 +25,23 @@ type BarkSlogHandler struct {
log *log.Logger
}

// WithAttrs method is an implementation of slog.Handler interface's method for BarkSlogHandler
// This allows a set of attributes to be added to slog package,
// but right now we're not supporting additional slog attributes.
// This method returns the handler as is for now.
func (handle *BarkSlogHandler) WithAttrs(attrs []slog.Attr) slog.Handler {
return slog.NewJSONHandler(os.Stdout, nil)
return handle
}

// WithGroup method is an implementation of slog.Handler interface's method for BarkSlogHandler
// This allows a group to be added to slog package, but right now we're not supporting slog groups.
// This method returns the handler as is for now.
func (handle *BarkSlogHandler) WithGroup(name string) slog.Handler {
return handle
}

// Enabled method is an implementation of slog.Handler interface's method for BarkSlogHandler
// This method defines which log levels are supported.
func (handle *BarkSlogHandler) Enabled(_ context.Context, level slog.Level) bool {
if level == LvlPanic || level == LvlAlert || level == LvlError ||
level == LvlWarning || level == LvlNotice || level == LvlInfo ||
Expand Down
1 change: 1 addition & 0 deletions client/channel.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ const ChannelCapacity = 100000

var PendingLogsChan chan models.BarkLog

// init allocates fixed memory for pending log channel
func init() {
PendingLogsChan = make(chan models.BarkLog, ChannelCapacity)
}
185 changes: 70 additions & 115 deletions client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ type Config struct {
AlertWebhook webhook
}

// parseMessage extracts LMID (Log Message Identifier) if a valid LMID exists in message string otherwise.
func (c *Config) parseMessage(msg string) models.BarkLog {
l := models.BarkLog{
ServiceName: c.ServiceName,
Expand Down Expand Up @@ -107,6 +108,7 @@ func (c *Config) parseMessage(msg string) models.BarkLog {
return l
}

// getLogLevelFromCharacter returns a string of log level for the first character of log level passed.
func (c *Config) getLogLevelFromCharacter(s string) string {
switch strings.ToUpper(s) {
case "P":
Expand All @@ -128,6 +130,7 @@ func (c *Config) getLogLevelFromCharacter(s string) string {
}
}

// getCharacterFromLogLevel returns a string of letter of log level for the log level string passed.
func (c *Config) getCharacterFromLogLevel(logLevel string) string {
switch logLevel {
case constants.Panic:
Expand All @@ -149,6 +152,10 @@ func (c *Config) getCharacterFromLogLevel(logLevel string) string {
}
}

// dispatchLogMessage is responsible for dispatching a log to server.
// This method takes in a log and sends it to PendingLogsChan if bulk send is enabled,
// otherwise if bulk send is disabled it creates a network request to send the log,
// in a new goroutine.
func (c *Config) dispatchLogMessage(l models.BarkLog) {
if c.BulkSend {
go InsertSingleRequest(l)
Expand All @@ -164,6 +171,7 @@ func (c *Config) dispatchLogMessage(l models.BarkLog) {
}
}

// Panic sends a LvlPanic log to server and prints the log if slog is enabled.
func (c *Config) Panic(message string) {
l := c.parseMessage(message)
l.LogLevel = constants.Panic
Expand All @@ -176,6 +184,8 @@ func (c *Config) Panic(message string) {
}
}

// Alert sends a LvlAlert log to server and prints the log if slog is enabled.
// This also initiates a AlertWebhook call.
func (c *Config) Alert(message string, blocking bool) {
l := c.parseMessage(message)
l.LogLevel = constants.Alert
Expand Down Expand Up @@ -212,6 +222,7 @@ func (c *Config) Alert(message string, blocking bool) {
}
}

// Error sends a LvlError level log to server and prints the log if slog is enabled.
func (c *Config) Error(message string) {
l := c.parseMessage(message)
l.LogLevel = constants.Error
Expand All @@ -223,6 +234,8 @@ func (c *Config) Error(message string) {
c.Slogger.Error(message)
}
}

// Warn sends a LvlWarning level log to server and prints the log if slog is enabled.
func (c *Config) Warn(message string) {
l := c.parseMessage(message)
l.LogLevel = constants.Warning
Expand All @@ -234,6 +247,8 @@ func (c *Config) Warn(message string) {
c.Slogger.Warn(message)
}
}

// Notice sends a LvlNotice level log to server and prints the log if slog is enabled.
func (c *Config) Notice(message string) {
l := c.parseMessage(message)
l.LogLevel = constants.Notice
Expand All @@ -245,6 +260,8 @@ func (c *Config) Notice(message string) {
c.Slogger.Log(context.Background(), LvlNotice, message)
}
}

// Info sends a LvlInfo level log to server and prints the log if slog is enabled.
func (c *Config) Info(message string) {
l := c.parseMessage(message)
l.LogLevel = constants.Info
Expand All @@ -257,6 +274,7 @@ func (c *Config) Info(message string) {
}
}

// Debug sends a LvlDebug level log to server and prints the log if slog is enabled.
func (c *Config) Debug(message string) {
l := c.parseMessage(message)
l.LogLevel = constants.Debug
Expand All @@ -269,6 +287,8 @@ func (c *Config) Debug(message string) {
}
}

// Default sends a Config.Default level log to server (specified while creating client)
// and prints the log if slog is enabled.
func (c *Config) Default(message string) {
l := c.parseMessage(message)
l.LogTime = time.Now().UTC()
Expand Down Expand Up @@ -297,6 +317,7 @@ func (c *Config) Default(message string) {
}
}

// Raw allows user to send a RawLog to server.
func (c *Config) Raw(rawLog RawLog, returnError bool) error {
// Try to parse the more data field
moreData, err := jsonObject.ToJsonObject(rawLog.MoreData)
Expand Down Expand Up @@ -349,6 +370,9 @@ func (c *Config) Raw(rawLog RawLog, returnError bool) error {
return nil
}

// Println sends logs to server based on LMID passed in message string.
// If the LMID is invalid an LvlInfo log level considered by default.
// This method prints the logs regardless if the slog is enabled or not.
func (c *Config) Println(message string) {
l := c.parseMessage(message)
l.LogTime = time.Now().UTC()
Expand Down Expand Up @@ -380,157 +404,86 @@ func (c *Config) Println(message string) {
}
}

// Printf performs the same operation as Config.Println but it accepts a format specifier.
func (c *Config) Printf(message string, format ...any) {
msg := fmt.Sprintf(message, format...)
l := c.parseMessage(msg)
l.LogTime = time.Now().UTC()
l.MoreData = jsonObject.EmptyNotNullJsonObject()
c.dispatchLogMessage(l)

if c.Slogger != nil {
switch l.LogLevel {
case PANIC:
c.Slogger.Log(context.Background(), LvlPanic, msg)
case ALERT:
c.Slogger.Log(context.Background(), LvlAlert, msg)
case ERROR:
c.Slogger.Error(msg)
case WARNING:
c.Slogger.Warn(msg)
case NOTICE:
c.Slogger.Log(context.Background(), LvlNotice, msg)
case DEBUG:
c.Slogger.Debug(msg)
case INFO:
fallthrough
default:
c.Slogger.Info(msg)
}
} else {
// In addition to sending the log to server, we should also print it!
fmt.Println(msg)
}
c.Println(msg)
}

// Panicf performs the same operation as Config.Panic but it accepts a format specifier.
func (c *Config) Panicf(message string, format ...any) {
message = fmt.Sprintf(message, format...)
l := c.parseMessage(message)
l.LogLevel = constants.Panic
l.LogTime = time.Now().UTC()
l.MoreData = jsonObject.EmptyNotNullJsonObject()
c.dispatchLogMessage(l)

if c.Slogger != nil {
c.Slogger.Log(context.Background(), LvlPanic, message)
}
c.Panic(message)
}

// Alertf performs the same operation as Config.Alert but it accepts a format specifier.
func (c *Config) Alertf(message string, blocking bool, format ...any) {
message = fmt.Sprintf(message, format...)
l := c.parseMessage(message)
l.LogLevel = constants.Alert
l.LogTime = time.Now().UTC()
l.MoreData = jsonObject.EmptyNotNullJsonObject()
c.dispatchLogMessage(l)

if c.AlertWebhook != nil {
if blocking {
err := c.AlertWebhook(l)
if err != nil {
if c.Slogger != nil {
c.Slogger.Log(context.Background(), LvlAlert, "unable to send alert")
} else {
fmt.Printf("E#1LR1V1 - Webhook failed to send. Error: %v | Original Log Message: %v\n", err, message)
}
}
} else {
go func() {
err := c.AlertWebhook(l)
if err != nil {
if c.Slogger != nil {
c.Slogger.Log(context.Background(), LvlAlert, "unable to send alert")
} else {
fmt.Printf("E#1LR1V1 - Webhook failed to send. Error: %v | Original Log Message: %v\n", err, message)
}
}
}()
}
}

if c.Slogger != nil {
c.Slogger.Log(context.Background(), LvlAlert, message)
}
c.Alert(message, blocking)
}

// Errorf performs the same operation as Config.Error but it accepts a format specifier.
func (c *Config) Errorf(message string, format ...any) {
message = fmt.Sprintf(message, format...)
l := c.parseMessage(message)
l.LogLevel = constants.Error
l.LogTime = time.Now().UTC()
l.MoreData = jsonObject.EmptyNotNullJsonObject()
c.dispatchLogMessage(l)

if c.Slogger != nil {
c.Slogger.Error(message)
}
c.Error(message)
}

// Warnf performs the same operation as Config.Warn but it accepts a format specifier.
func (c *Config) Warnf(message string, format ...any) {
message = fmt.Sprintf(message, format...)
l := c.parseMessage(message)
l.LogLevel = constants.Warning
l.LogTime = time.Now().UTC()
l.MoreData = jsonObject.EmptyNotNullJsonObject()
c.dispatchLogMessage(l)

if c.Slogger != nil {
c.Slogger.Warn(message)
}
c.Warn(message)
}

// Noticef performs the same operation as Config.Notice but it accepts a format specifier.
func (c *Config) Noticef(message string, format ...any) {
message = fmt.Sprintf(message, format...)
l := c.parseMessage(message)
l.LogLevel = constants.Notice
l.LogTime = time.Now().UTC()
l.MoreData = jsonObject.EmptyNotNullJsonObject()
c.dispatchLogMessage(l)

if c.Slogger != nil {
c.Slogger.Log(context.Background(), LvlNotice, message)
}
c.Notice(message)
}

// Infof performs the same operation as Config.Info but it accepts a format specifier.
func (c *Config) Infof(message string, format ...any) {
message = fmt.Sprintf(message, format...)
l := c.parseMessage(message)
l.LogLevel = constants.Info
l.LogTime = time.Now().UTC()
l.MoreData = jsonObject.EmptyNotNullJsonObject()
c.dispatchLogMessage(l)

if c.Slogger != nil {
c.Slogger.Info(message)
}
c.Info(message)
}

// Debugf performs the same operation as Config.Debug but it accepts a format specifier.
func (c *Config) Debugf(message string, format ...any) {
message = fmt.Sprintf(message, format...)
l := c.parseMessage(message)
l.LogLevel = constants.Debug
l.LogTime = time.Now().UTC()
l.MoreData = jsonObject.EmptyNotNullJsonObject()
c.dispatchLogMessage(l)

if c.Slogger != nil {
c.Slogger.Debug(message)
}
c.Debug(message)
}

// SetAlertWebhook sets a webhook to be used by Config.Alert method
func (c *Config) SetAlertWebhook(f webhook) {
c.AlertWebhook = f
}

// NewClient creates and returns a new Config object with the given parameters.
// A Config object represents the configuration for logging to a remote server.
// Config object is the main point interactions between user and bark client library.
//
// The url parameter is the base URL of the remote bark server where the logs will be sent.
// It must be a valid URL string.
//
// The errLevel parameter is the error level for logging. It must be one of the constants
// defined in the constants package, such as INFO, WARN, ERROR, etc. If an invalid value
// is given, the function will print a warning message and use INFO as the default level.
//
// The svcName parameter is the name of the service that is logging. It must be a non-empty
// string. If an empty string is given, the function will print a warning message and use
// constants.DefaultLogServiceName as the default value.
//
// The sessName parameter is the name of the session that is logging. It must be a non-empty
// string. If an empty string is given, the function will print a warning message and use
// appRuntime.SessionName as the default value.
//
// The enableSlog parameter is a boolean flag that indicates whether to enable slog logging
// to standard output. If true, the function will create and assign a new slog.Logger object
// to the Config object. If false, the Config object will have a nil Slogger field.
//
// The enableBulkSend parameter is a boolean flag that indicates whether to enable bulk sending
// of logs to the remote server. If true, the function will start a goroutine that periodically
// sends all the buffered logs to the server. If false, the logs will be sent individually as
// they are generated.
func NewClient(url, errLevel, svcName, sessName string, enableSlog bool, enableBulkSend bool) *Config {
if !isValid(errLevel) {
fmt.Printf("L#1LPYG2 - %v is not an acceptable log level. %v will be used as the default log level", errLevel, constants.DefaultLogLevel)
Expand Down Expand Up @@ -581,6 +534,8 @@ func (c *Config) WithSlogHandler(handler slog.Handler) {
c.Slogger = NewWithCustomHandler(handler)
}

// WaitAndEnd will wait for all logs to be sent to server.
// This is an optional blocking call if the there are unsent logs.
func (c *Config) WaitAndEnd() {
Wg.Wait()
}
1 change: 1 addition & 0 deletions client/ingestion.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"github.com/techrail/bark/models"
)

// InsertSingleRequest sends logEntry to PendingLogChan
func InsertSingleRequest(logEntry models.BarkLog) {
if len(PendingLogsChan) > ChannelCapacity-1 {
fmt.Printf("E#1LB9MN - Channel is full. Cannot push. Log received: | %v\n", logEntry)
Expand Down
1 change: 1 addition & 0 deletions client/log_level_type.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ const (
DEBUG = "DEBUG"
)

// isValid returns true of the lvl string is a valid log level.
func isValid(lvl string) bool {
switch lvl {
case PANIC:
Expand Down
Loading

0 comments on commit dc4352f

Please sign in to comment.