Skip to content

Commit

Permalink
Refactor config and log
Browse files Browse the repository at this point in the history
  • Loading branch information
minhduc140583 committed Sep 28, 2024
1 parent f1c749c commit 217b062
Show file tree
Hide file tree
Showing 11 changed files with 577 additions and 46 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# mq
![Message Queue](https://cdn-images-1.medium.com/max/800/1*UbKJu2BcAYim8_oJg8Ns6A.png)
![Message Queue](https://cdn-images-1.medium.com/max/800/1*a3_1glo06Fgh-pkqIATyng.png)
## Message Queue
A message queue is a communication method used in software systems to exchange information between different components or services asynchronously. It provides a way to send messages between producers (senders) and consumers (receivers) without requiring both parties to interact with the message queue at the same time. This decoupling allows for more scalable, reliable, and flexible system architectures.

Expand Down
103 changes: 95 additions & 8 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@ package config
import (
"fmt"
"github.com/spf13/viper"
"io/ioutil"
"log"
"os"
"reflect"
"strconv"
"strings"
"time"
)

func Load(c interface{}, fileNames ...string) error {
Expand Down Expand Up @@ -111,7 +112,7 @@ func LoadConfigWithEnv(parentPath string, directory string, env string, c interf
// BindEnvs function will bind ymal file to struc model
func BindEnvs(conf interface{}, parts ...string) error {
ifv := reflect.Indirect(reflect.ValueOf(conf))
ift := reflect.TypeOf(ifv)
ift := ifv.Type()
num := min(ift.NumField(), ifv.NumField())
for i := 0; i < num; i++ {
v := ifv.Field(i)
Expand All @@ -122,9 +123,15 @@ func BindEnvs(conf interface{}, parts ...string) error {
}
switch v.Kind() {
case reflect.Struct:
return BindEnvs(v.Interface(), append(parts, tv)...)
err := BindEnvs(v.Interface(), append(parts, tv)...)
if err != nil {
return err
}
default:
return viper.BindEnv(strings.Join(append(parts, tv), "."))
err := viper.BindEnv(strings.Join(append(parts, tv), "."))
if err != nil {
return err
}
}
}
return nil
Expand Down Expand Up @@ -212,15 +219,15 @@ func LoadFileWithPath(parentPath string, directory string, env string, filename
file = "./" + parentPath + "/" + directory + "/" + filename[0:indexDot] + "-" + env + filename[indexDot:]
}
if fileExists(file) {
return ioutil.ReadFile(file)
return os.ReadFile(file)
}
}
}
file := "./" + directory + "/" + filename
if !fileExists(file) {
file = "./" + parentPath + "/" + directory + "/" + filename
}
return ioutil.ReadFile(file)
return os.ReadFile(file)
} else {
if len(env) > 0 {
indexDot := strings.LastIndex(filename, ".")
Expand All @@ -230,15 +237,15 @@ func LoadFileWithPath(parentPath string, directory string, env string, filename
file = "./" + parentPath + "/" + filename[0:indexDot] + "-" + env + filename[indexDot:]
}
if fileExists(file) {
return ioutil.ReadFile(file)
return os.ReadFile(file)
}
}
}
file := "./" + filename
if !fileExists(file) {
file = "./" + parentPath + "/" + filename
}
return ioutil.ReadFile(file)
return os.ReadFile(file)
}
}
func LoadFileWithEnv(env string, filename string) ([]byte, error) {
Expand Down Expand Up @@ -282,3 +289,83 @@ func fileExists(filename string) bool {
}
return !info.IsDir()
}

func MakeDurations(vs []int64) []time.Duration {
durations := make([]time.Duration, 0)
for _, v := range vs {
d := time.Duration(v) * time.Second
durations = append(durations, d)
}
return durations
}
func MakeArray(v interface{}, prefix string, max int) []int64 {
var ar []int64
v2 := reflect.Indirect(reflect.ValueOf(v))
for i := 1; i <= max; i++ {
fn := prefix + strconv.Itoa(i)
v3 := v2.FieldByName(fn).Interface().(int64)
if v3 > 0 {
ar = append(ar, v3)
} else {
return ar
}
}
return ar
}
func DurationsFromValue(v interface{}, prefix string, max int) []time.Duration {
arr := MakeArray(v, prefix, max)
return MakeDurations(arr)
}

type Retry struct {
Retry1 int64 `mapstructure:"1" json:"retry1,omitempty" gorm:"column:retry1" bson:"retry1,omitempty" dynamodbav:"retry1,omitempty" firestore:"retry1,omitempty"`
Retry2 int64 `mapstructure:"2" json:"retry2,omitempty" gorm:"column:retry2" bson:"retry2,omitempty" dynamodbav:"retry2,omitempty" firestore:"retry2,omitempty"`
Retry3 int64 `mapstructure:"3" json:"retry3,omitempty" gorm:"column:retry3" bson:"retry3,omitempty" dynamodbav:"retry3,omitempty" firestore:"retry3,omitempty"`
Retry4 int64 `mapstructure:"4" json:"retry4,omitempty" gorm:"column:retry4" bson:"retry4,omitempty" dynamodbav:"retry4,omitempty" firestore:"retry4,omitempty"`
Retry5 int64 `mapstructure:"5" json:"retry5,omitempty" gorm:"column:retry5" bson:"retry5,omitempty" dynamodbav:"retry5,omitempty" firestore:"retry5,omitempty"`
Retry6 int64 `mapstructure:"6" json:"retry6,omitempty" gorm:"column:retry6" bson:"retry6,omitempty" dynamodbav:"retry6,omitempty" firestore:"retry6,omitempty"`
Retry7 int64 `mapstructure:"7" json:"retry7,omitempty" gorm:"column:retry7" bson:"retry7,omitempty" dynamodbav:"retry7,omitempty" firestore:"retry7,omitempty"`
Retry8 int64 `mapstructure:"8" json:"retry8,omitempty" gorm:"column:retry8" bson:"retry8,omitempty" dynamodbav:"retry8,omitempty" firestore:"retry8,omitempty"`
Retry9 int64 `mapstructure:"9" json:"retry9,omitempty" gorm:"column:retry9" bson:"retry9,omitempty" dynamodbav:"retry9,omitempty" firestore:"retry9,omitempty"`
Retry10 int64 `mapstructure:"10" json:"retry10,omitempty" gorm:"column:retry10" bson:"retry10,omitempty" dynamodbav:"retry10,omitempty" firestore:"retry10,omitempty"`
Retry11 int64 `mapstructure:"11" json:"retry11,omitempty" gorm:"column:retry11" bson:"retry11,omitempty" dynamodbav:"retry11,omitempty" firestore:"retry11,omitempty"`
Retry12 int64 `mapstructure:"12" json:"retry12,omitempty" gorm:"column:retry12" bson:"retry12,omitempty" dynamodbav:"retry12,omitempty" firestore:"retry12,omitempty"`
Retry13 int64 `mapstructure:"13" json:"retry13,omitempty" gorm:"column:retry13" bson:"retry13,omitempty" dynamodbav:"retry13,omitempty" firestore:"retry13,omitempty"`
Retry14 int64 `mapstructure:"14" json:"retry14,omitempty" gorm:"column:retry14" bson:"retry14,omitempty" dynamodbav:"retry14,omitempty" firestore:"retry14,omitempty"`
Retry15 int64 `mapstructure:"15" json:"retry15,omitempty" gorm:"column:retry15" bson:"retry15,omitempty" dynamodbav:"retry15,omitempty" firestore:"retry15,omitempty"`
Retry16 int64 `mapstructure:"16" json:"retry16,omitempty" gorm:"column:retry16" bson:"retry16,omitempty" dynamodbav:"retry16,omitempty" firestore:"retry16,omitempty"`
Retry17 int64 `mapstructure:"17" json:"retry17,omitempty" gorm:"column:retry17" bson:"retry17,omitempty" dynamodbav:"retry17,omitempty" firestore:"retry17,omitempty"`
Retry18 int64 `mapstructure:"18" json:"retry18,omitempty" gorm:"column:retry18" bson:"retry18,omitempty" dynamodbav:"retry18,omitempty" firestore:"retry18,omitempty"`
Retry19 int64 `mapstructure:"19" json:"retry19,omitempty" gorm:"column:retry19" bson:"retry19,omitempty" dynamodbav:"retry19,omitempty" firestore:"retry19,omitempty"`
Retry20 int64 `mapstructure:"20" json:"retry20,omitempty" gorm:"column:retry20" bson:"retry20,omitempty" dynamodbav:"retry20,omitempty" firestore:"retry20,omitempty"`
Retry21 int64 `mapstructure:"21" json:"retry21,omitempty" gorm:"column:retry21" bson:"retry21,omitempty" dynamodbav:"retry21,omitempty" firestore:"retry21,omitempty"`
Retry22 int64 `mapstructure:"22" json:"retry22,omitempty" gorm:"column:retry22" bson:"retry22,omitempty" dynamodbav:"retry22,omitempty" firestore:"retry22,omitempty"`
Retry23 int64 `mapstructure:"23" json:"retry23,omitempty" gorm:"column:retry23" bson:"retry23,omitempty" dynamodbav:"retry23,omitempty" firestore:"retry23,omitempty"`
Retry24 int64 `mapstructure:"24" json:"retry24,omitempty" gorm:"column:retry24" bson:"retry24,omitempty" dynamodbav:"retry24,omitempty" firestore:"retry24,omitempty"`
Retry25 int64 `mapstructure:"25" json:"retry25,omitempty" gorm:"column:retry25" bson:"retry25,omitempty" dynamodbav:"retry25,omitempty" firestore:"retry25,omitempty"`
Retry26 int64 `mapstructure:"26" json:"retry26,omitempty" gorm:"column:retry26" bson:"retry26,omitempty" dynamodbav:"retry26,omitempty" firestore:"retry26,omitempty"`
Retry27 int64 `mapstructure:"27" json:"retry27,omitempty" gorm:"column:retry27" bson:"retry27,omitempty" dynamodbav:"retry27,omitempty" firestore:"retry27,omitempty"`
Retry28 int64 `mapstructure:"28" json:"retry28,omitempty" gorm:"column:retry28" bson:"retry28,omitempty" dynamodbav:"retry28,omitempty" firestore:"retry28,omitempty"`
Retry29 int64 `mapstructure:"29" json:"retry29,omitempty" gorm:"column:retry29" bson:"retry29,omitempty" dynamodbav:"retry29,omitempty" firestore:"retry29,omitempty"`
Retry30 int64 `mapstructure:"30" json:"retry30,omitempty" gorm:"column:retry30" bson:"retry30,omitempty" dynamodbav:"retry30,omitempty" firestore:"retry30,omitempty"`
Retry31 int64 `mapstructure:"31" json:"retry31,omitempty" gorm:"column:retry31" bson:"retry31,omitempty" dynamodbav:"retry31,omitempty" firestore:"retry31,omitempty"`
Retry32 int64 `mapstructure:"32" json:"retry32,omitempty" gorm:"column:retry32" bson:"retry32,omitempty" dynamodbav:"retry32,omitempty" firestore:"retry32,omitempty"`
Retry33 int64 `mapstructure:"33" json:"retry33,omitempty" gorm:"column:retry33" bson:"retry33,omitempty" dynamodbav:"retry33,omitempty" firestore:"retry33,omitempty"`
Retry34 int64 `mapstructure:"34" json:"retry34,omitempty" gorm:"column:retry34" bson:"retry34,omitempty" dynamodbav:"retry34,omitempty" firestore:"retry34,omitempty"`
Retry35 int64 `mapstructure:"35" json:"retry35,omitempty" gorm:"column:retry35" bson:"retry35,omitempty" dynamodbav:"retry35,omitempty" firestore:"retry35,omitempty"`
Retry36 int64 `mapstructure:"36" json:"retry36,omitempty" gorm:"column:retry36" bson:"retry36,omitempty" dynamodbav:"retry36,omitempty" firestore:"retry36,omitempty"`
Retry37 int64 `mapstructure:"37" json:"retry37,omitempty" gorm:"column:retry37" bson:"retry37,omitempty" dynamodbav:"retry37,omitempty" firestore:"retry37,omitempty"`
Retry38 int64 `mapstructure:"38" json:"retry38,omitempty" gorm:"column:retry38" bson:"retry38,omitempty" dynamodbav:"retry38,omitempty" firestore:"retry38,omitempty"`
Retry39 int64 `mapstructure:"39" json:"retry39,omitempty" gorm:"column:retry39" bson:"retry39,omitempty" dynamodbav:"retry39,omitempty" firestore:"retry39,omitempty"`
Retry40 int64 `mapstructure:"40" json:"retry40,omitempty" gorm:"column:retry40" bson:"retry40,omitempty" dynamodbav:"retry40,omitempty" firestore:"retry40,omitempty"`
Retry41 int64 `mapstructure:"41" json:"retry41,omitempty" gorm:"column:retry41" bson:"retry41,omitempty" dynamodbav:"retry41,omitempty" firestore:"retry41,omitempty"`
Retry42 int64 `mapstructure:"42" json:"retry42,omitempty" gorm:"column:retry42" bson:"retry42,omitempty" dynamodbav:"retry42,omitempty" firestore:"retry42,omitempty"`
Retry43 int64 `mapstructure:"43" json:"retry43,omitempty" gorm:"column:retry43" bson:"retry43,omitempty" dynamodbav:"retry43,omitempty" firestore:"retry43,omitempty"`
Retry44 int64 `mapstructure:"44" json:"retry44,omitempty" gorm:"column:retry44" bson:"retry44,omitempty" dynamodbav:"retry44,omitempty" firestore:"retry44,omitempty"`
Retry45 int64 `mapstructure:"45" json:"retry45,omitempty" gorm:"column:retry45" bson:"retry45,omitempty" dynamodbav:"retry45,omitempty" firestore:"retry45,omitempty"`
Retry46 int64 `mapstructure:"46" json:"retry46,omitempty" gorm:"column:retry46" bson:"retry46,omitempty" dynamodbav:"retry46,omitempty" firestore:"retry46,omitempty"`
Retry47 int64 `mapstructure:"47" json:"retry47,omitempty" gorm:"column:retry47" bson:"retry47,omitempty" dynamodbav:"retry47,omitempty" firestore:"retry47,omitempty"`
Retry48 int64 `mapstructure:"48" json:"retry48,omitempty" gorm:"column:retry48" bson:"retry48,omitempty" dynamodbav:"retry48,omitempty" firestore:"retry48,omitempty"`
Retry49 int64 `mapstructure:"49" json:"retry49,omitempty" gorm:"column:retry49" bson:"retry49,omitempty" dynamodbav:"retry49,omitempty" firestore:"retry49,omitempty"`
Retry50 int64 `mapstructure:"50" json:"retry50,omitempty" gorm:"column:retry50" bson:"retry50,omitempty" dynamodbav:"retry50,omitempty" firestore:"retry50,omitempty"`
}
19 changes: 10 additions & 9 deletions log/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,17 @@ package log
import "github.com/sirupsen/logrus"

type Config struct {
Level string `mapstructure:"level" json:"level,omitempty" gorm:"column:level" bson:"level,omitempty" dynamodbav:"level,omitempty" firestore:"level,omitempty"`
Duration string `mapstructure:"duration" json:"duration,omitempty" gorm:"column:duration" bson:"duration,omitempty" dynamodbav:"duration,omitempty" firestore:"duration,omitempty"`
Fields string `mapstructure:"fields" json:"fields,omitempty" gorm:"column:fields" bson:"fields,omitempty" dynamodbav:"fields,omitempty" firestore:"fields,omitempty"`
FieldMap string `mapstructure:"field_map" json:"fieldMap,omitempty" gorm:"column:fieldmap" bson:"fieldMap,omitempty" dynamodbav:"fieldMap,omitempty" firestore:"fieldMap,omitempty"`
Map *logrus.FieldMap `mapstructure:"map" json:"map,omitempty" gorm:"column:map" bson:"map,omitempty" dynamodbav:"map,omitempty" firestore:"map,omitempty"`
TimestampFormat string `mapstructure:"timestamp_format" json:"timestampFormat,omitempty" gorm:"column:timestampformat" bson:"timestampFormat,omitempty" dynamodbav:"timestampFormat,omitempty" firestore:"timestampFormat,omitempty"`
Level string `yaml:"level" mapstructure:"level" json:"level,omitempty" gorm:"column:level" bson:"level,omitempty" dynamodbav:"level,omitempty" firestore:"level,omitempty"`
Output string `yaml:"output" mapstructure:"output" json:"output,omitempty" gorm:"column:output" bson:"output,omitempty" dynamodbav:"output,omitempty" firestore:"output,omitempty"`
Duration string `yaml:"duration" mapstructure:"duration" json:"duration,omitempty" gorm:"column:duration" bson:"duration,omitempty" dynamodbav:"duration,omitempty" firestore:"duration,omitempty"`
Fields string `yaml:"fields" mapstructure:"fields" json:"fields,omitempty" gorm:"column:fields" bson:"fields,omitempty" dynamodbav:"fields,omitempty" firestore:"fields,omitempty"`
FieldMap string `yaml:"field_map" mapstructure:"field_map" json:"fieldMap,omitempty" gorm:"column:fieldmap" bson:"fieldMap,omitempty" dynamodbav:"fieldMap,omitempty" firestore:"fieldMap,omitempty"`
Map *logrus.FieldMap `yaml:"map" mapstructure:"map" json:"map,omitempty" gorm:"column:map" bson:"map,omitempty" dynamodbav:"map,omitempty" firestore:"map,omitempty"`
TimestampFormat string `yaml:"timestamp_format" mapstructure:"timestamp_format" json:"timestampFormat,omitempty" gorm:"column:timestampformat" bson:"timestampFormat,omitempty" dynamodbav:"timestampFormat,omitempty" firestore:"timestampFormat,omitempty"`
}

type FieldConfig struct {
FieldMap string `mapstructure:"field_map" json:"fieldMap,omitempty" gorm:"column:fieldmap" bson:"fieldMap,omitempty" dynamodbav:"fieldMap,omitempty" firestore:"fieldMap,omitempty"`
Duration string `mapstructure:"duration" json:"duration,omitempty" gorm:"column:duration" bson:"duration,omitempty" dynamodbav:"duration,omitempty" firestore:"duration,omitempty"`
Fields *[]string `mapstructure:"fields" json:"fields,omitempty" gorm:"column:fields" bson:"fields,omitempty" dynamodbav:"fields,omitempty" firestore:"fields,omitempty"`
FieldMap string `yaml:"field_map" mapstructure:"field_map" json:"fieldMap,omitempty" gorm:"column:fieldmap" bson:"fieldMap,omitempty" dynamodbav:"fieldMap,omitempty" firestore:"fieldMap,omitempty"`
Duration string `yaml:"duration" mapstructure:"duration" json:"duration,omitempty" gorm:"column:duration" bson:"duration,omitempty" dynamodbav:"duration,omitempty" firestore:"duration,omitempty"`
Fields *[]string `yaml:"fields" mapstructure:"fields" json:"fields,omitempty" gorm:"column:fields" bson:"fields,omitempty" dynamodbav:"fields,omitempty" firestore:"fields,omitempty"`
}
80 changes: 79 additions & 1 deletion log/logrus.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,20 @@ import (
"encoding/json"
"fmt"
"github.com/sirupsen/logrus"
"io"
"os"
"strings"
"time"
)

var fieldConfig FieldConfig
var logger *logrus.Logger

func Initialize(c Config) *logrus.Logger {
func Initialize(c Config, opts...func(logLocation string, rotationTime time.Duration) (io.Writer, func() error)) *logrus.Logger {
var getWriter func(logLocation string, rotationTime time.Duration) (io.Writer, func() error)
if len(opts) > 0 && opts[0] != nil {
getWriter = opts[0]
}
fieldConfig.FieldMap = c.FieldMap
if len(c.Duration) > 0 {
fieldConfig.Duration = c.Duration
Expand All @@ -36,6 +42,16 @@ func Initialize(c Config) *logrus.Logger {
x := &formatter
l.SetFormatter(x)
logrus.SetFormatter(x)
if len(c.Output) > 0 && getWriter != nil {
CreatePath(c.Output)
w, close := getWriter(c.Output, 24*time.Hour)
l.SetOutput(io.MultiWriter(os.Stderr, w))
logrus.SetOutput(io.MultiWriter(os.Stderr, w))
handler := func() {
close()
}
logrus.RegisterExitHandler(handler)
}
if len(c.Level) > 0 {
if level, err := logrus.ParseLevel(c.Level); err == nil {
l.SetLevel(level)
Expand Down Expand Up @@ -222,6 +238,9 @@ func Panicf(ctx context.Context, format string, args ...interface{}) {

func BuildLogFields(m map[string]interface{}) logrus.Fields {
logFields := logrus.Fields{}
if m == nil || len(m) == 0 {
return logFields
}
for k, v := range m {
logFields[k] = v
}
Expand Down Expand Up @@ -257,6 +276,15 @@ func LogfWithFields(ctx context.Context, level logrus.Level, fields map[string]i
}
}

func TraceWithFields(ctx context.Context, msg interface{}, fields map[string]interface{}) {
LogWithFields(ctx, logrus.TraceLevel, msg, fields)
}
func TracefWithFields(ctx context.Context, fields map[string]interface{}, format string, args ...interface{}) {
if logrus.IsLevelEnabled(logrus.TraceLevel) {
msg := fmt.Sprintf(format, args...)
LogWithFields(ctx, logrus.TraceLevel, msg, fields)
}
}
func DebugWithFields(ctx context.Context, msg interface{}, fields map[string]interface{}) {
LogWithFields(ctx, logrus.DebugLevel, msg, fields)
}
Expand Down Expand Up @@ -327,3 +355,53 @@ func FatalFields(ctx context.Context, msg string, fields map[string]interface{})
func PanicFields(ctx context.Context, msg string, fields map[string]interface{}) {
LogWithFields(ctx, logrus.PanicLevel, msg, fields)
}

func LogTrace(ctx context.Context, msg string, opts ...map[string]interface{}) {
if len(opts) > 0 {
TraceWithFields(ctx, msg, opts[0])
} else {
TraceWithFields(ctx, msg, nil)
}
}
func LogDebug(ctx context.Context, msg string, opts ...map[string]interface{}) {
if len(opts) > 0 {
DebugWithFields(ctx, msg, opts[0])
} else {
DebugWithFields(ctx, msg, nil)
}
}
func LogInfo(ctx context.Context, msg string, opts ...map[string]interface{}) {
if len(opts) > 0 {
InfoWithFields(ctx, msg, opts[0])
} else {
InfoWithFields(ctx, msg, nil)
}
}
func LogWarn(ctx context.Context, msg string, opts ...map[string]interface{}) {
if len(opts) > 0 {
WarnWithFields(ctx, msg, opts[0])
} else {
WarnWithFields(ctx, msg, nil)
}
}
func LogError(ctx context.Context, msg string, opts ...map[string]interface{}) {
if len(opts) > 0 {
ErrorWithFields(ctx, msg, opts[0])
} else {
ErrorWithFields(ctx, msg, nil)
}
}
func LogFatal(ctx context.Context, msg string, opts ...map[string]interface{}) {
if len(opts) > 0 {
FatalWithFields(ctx, msg, opts[0])
} else {
FatalWithFields(ctx, msg, nil)
}
}
func LogPanic(ctx context.Context, msg string, opts ...map[string]interface{}) {
if len(opts) > 0 {
PanicWithFields(ctx, msg, opts[0])
} else {
PanicWithFields(ctx, msg, nil)
}
}
Loading

0 comments on commit 217b062

Please sign in to comment.