feat (user): add logger on crud

This commit is contained in:
dpurbosakti
2025-08-20 09:36:13 +07:00
parent d476a31422
commit b20380b1f6
3 changed files with 251 additions and 45 deletions
+237 -42
View File
@@ -26,17 +26,13 @@ func Create(input e.CreateDto) (*d.Data, error) {
}
// Start log
event.Action = "Create"
event.Status = "started"
pl.SetLogInfo(event, input)
pl.SetLogInfo(&event, input, "started", "create")
err := dg.I.Transaction(func(tx *gorm.DB) error {
for i := range createPreMw {
mwName := fmt.Sprintf("createPreMw[%d]", i)
event.Action = mwName
event.Status = "started"
pl.SetLogInfo(event, data)
pl.SetLogInfo(&event, data, "started", mwName)
if err := createPreMw[i](&input, &data, tx); err != nil {
event.Status = "failed"
@@ -48,13 +44,10 @@ func Create(input e.CreateDto) (*d.Data, error) {
return pl.SetLogError(event, data)
}
event.Status = "completed"
pl.SetLogInfo(event, nil)
pl.SetLogInfo(&event, nil, "complete")
}
event.Action = "DBCreate"
event.Status = "started"
pl.SetLogInfo(event, data)
pl.SetLogInfo(&event, data, "started", "DBCreate")
_, err := CreateData(&data, tx)
if err != nil {
event.Status = "failed"
@@ -66,15 +59,12 @@ func Create(input e.CreateDto) (*d.Data, error) {
return pl.SetLogError(event, data)
}
event.Status = "completed"
pl.SetLogInfo(event, nil)
pl.SetLogInfo(&event, nil, "complete")
for i := range createPostMw {
mwName := fmt.Sprintf("createPostMw[%d]", i)
event.Action = mwName
event.Status = "started"
pl.SetLogInfo(event, input)
pl.SetLogInfo(&event, input, "started", mwName)
if err := createPostMw[i](&input, &data, tx); err != nil {
event.Status = "failed"
event.ErrInfo = pl.ErrorInfo{
@@ -86,8 +76,7 @@ func Create(input e.CreateDto) (*d.Data, error) {
}
}
event.Status = "completed"
pl.SetLogInfo(event, nil)
pl.SetLogInfo(&event, nil, "complete")
return nil
})
@@ -111,22 +100,64 @@ func ReadList(input e.ReadListDto) (*d.Data, error) {
var dataList []e.User
var metaList *e.MetaDto
var err error
event := pl.Event{
Feature: "ReadList",
Source: source,
}
// Start log
pl.SetLogInfo(&event, input, "started", "readList")
err = dg.I.Transaction(func(tx *gorm.DB) error {
for i := range readListPreMw {
mwName := fmt.Sprintf("readListPreMw[%d]", i)
pl.SetLogInfo(&event, input, "started", mwName)
if err := readListPreMw[i](&input, data, tx); err != nil {
return nil
event.Status = "failed"
event.ErrInfo = pl.ErrorInfo{
Code: "MW_PRE_FAILED", // TODO: add to lang json
Detail: fmt.Sprintf("Pre-middleware %s failed", mwName),
Raw: err,
}
return pl.SetLogError(event, input)
}
pl.SetLogInfo(&event, nil, "complete")
}
pl.SetLogInfo(&event, input, "started", "DBReadList")
dataList, metaList, err = ReadListData(input, tx)
if err != nil {
return err
event.Status = "failed"
event.ErrInfo = pl.ErrorInfo{
Code: "data-read-list-fail",
Detail: "Database read list failed",
Raw: err,
}
return pl.SetLogError(event, input)
}
pl.SetLogInfo(&event, nil, "complete")
for i := range readListPostMw {
mwName := fmt.Sprintf("readListPostMw[%d]", i)
pl.SetLogInfo(&event, input, "started", mwName)
if err := readListPostMw[i](&input, data, tx); err != nil {
return nil
event.Status = "failed"
event.ErrInfo = pl.ErrorInfo{
Code: "MW_POST_FAILED", // TODO: add to lang json
Detail: fmt.Sprintf("Post-middleware %s failed", mwName),
Raw: err,
}
return pl.SetLogError(event, input)
}
pl.SetLogInfo(&event, nil, "complete")
}
return nil
@@ -152,21 +183,66 @@ func ReadList(input e.ReadListDto) (*d.Data, error) {
func ReadDetail(input e.ReadDetailDto) (*d.Data, error) {
var data *e.User
var err error
event := pl.Event{
Feature: "ReadDetail",
Source: source,
}
// Start log
pl.SetLogInfo(&event, input, "started", "readDetail")
err = dg.I.Transaction(func(tx *gorm.DB) error {
for i := range readDetailPreMw {
mwName := fmt.Sprintf("readDetailPreMw[%d]", i)
pl.SetLogInfo(&event, input, "started", mwName)
if err := readDetailPreMw[i](&input, data, tx); err != nil {
return nil
event.Status = "failed"
event.ErrInfo = pl.ErrorInfo{
Code: "MW_PRE_FAILED", // TODO: add to lang json
Detail: fmt.Sprintf("Pre-middleware %s failed", mwName),
Raw: err,
}
return pl.SetLogError(event, input)
}
pl.SetLogInfo(&event, nil, "complete")
}
pl.SetLogInfo(&event, input, "started", "DBReadDetail")
data, err = ReadDetailData(input, tx)
if err != nil {
return err
}
for i := range readDetailPostMw {
if err := readDetailPostMw[i](&input, data, tx); err != nil {
return nil
event.Status = "failed"
event.ErrInfo = pl.ErrorInfo{
Code: "data-read-detail-fail",
Detail: "Database read detail failed",
Raw: err,
}
return pl.SetLogError(event, input)
}
pl.SetLogInfo(&event, nil, "complete")
for i := range readDetailPostMw {
mwName := fmt.Sprintf("readDetailPostMw[%d]", i)
pl.SetLogInfo(&event, data, "started", mwName)
if err := readDetailPostMw[i](&input, data, tx); err != nil {
event.Status = "failed"
event.ErrInfo = pl.ErrorInfo{
Code: "MW_POST_FAILED", // TODO: add to lang json
Detail: fmt.Sprintf("Post-middleware %s failed", mwName),
Raw: err,
}
return pl.SetLogError(event, data)
}
pl.SetLogInfo(&event, nil, "complete")
}
return nil
})
@@ -188,29 +264,93 @@ func Update(input e.UpdateDto) (*d.Data, error) {
rdDto := e.ReadDetailDto{Id: input.Id}
var data *e.User
var err error
event := pl.Event{
Feature: "Update",
Source: source,
}
// Start log
pl.SetLogInfo(&event, input, "started", "update")
err = dg.I.Transaction(func(tx *gorm.DB) error {
pl.SetLogInfo(&event, rdDto, "started", "DBReadDetail")
data, err = ReadDetailData(rdDto, tx)
if err != nil {
return nil
event.Status = "failed"
event.ErrInfo = pl.ErrorInfo{
Code: "data-read-detail-fail",
Detail: "Database read detail failed",
Raw: err,
}
return pl.SetLogError(event, rdDto)
}
pl.SetLogInfo(&event, nil, "complete")
pl.SetLogInfo(&event, input, "started", "setUpdate")
err = setUpdate(input, data)
if err != nil {
return err
event.Status = "failed"
event.ErrInfo = pl.ErrorInfo{
Code: "set-update-fail",
Detail: "Set update data failed",
Raw: err,
}
return pl.SetLogError(event, input)
}
pl.SetLogInfo(&event, nil, "complete")
for i := range updatePreMw {
mwName := fmt.Sprintf("updatePreMw[%d]", i)
pl.SetLogInfo(&event, data, "started", mwName)
if err := updatePreMw[i](&rdDto, data, tx); err != nil {
return nil
event.Status = "failed"
event.ErrInfo = pl.ErrorInfo{
Code: "MW_PRE_FAILED", // TODO: add to lang json
Detail: fmt.Sprintf("Pre-middleware %s failed", mwName),
Raw: err,
}
return pl.SetLogError(event, data)
}
pl.SetLogInfo(&event, nil, "complete")
}
pl.SetLogInfo(&event, data, "started", "DBUpdate")
if err := UpdateData(*data, tx); err != nil {
return nil
}
for i := range updatePostMw {
if err := updatePostMw[i](&rdDto, data, tx); err != nil {
return nil
event.Status = "failed"
event.ErrInfo = pl.ErrorInfo{
Code: "data-update-fail",
Detail: "Database update failed",
Raw: err,
}
return pl.SetLogError(event, data)
}
pl.SetLogInfo(&event, nil, "complete")
for i := range updatePostMw {
mwName := fmt.Sprintf("updatePostMw[%d]", i)
pl.SetLogInfo(&event, data, "started", mwName)
if err := updatePostMw[i](&rdDto, data, tx); err != nil {
event.Status = "failed"
event.ErrInfo = pl.ErrorInfo{
Code: "MW_POST_FAILED", // TODO: add to lang json
Detail: fmt.Sprintf("Post-middleware %s failed", mwName),
Raw: err,
}
return pl.SetLogError(event, data)
}
pl.SetLogInfo(&event, nil, "complete")
}
return nil
})
@@ -233,24 +373,79 @@ func Delete(input e.DeleteDto) (*d.Data, error) {
rdDto := e.ReadDetailDto{Id: input.Id}
var data *e.User
var err error
event := pl.Event{
Feature: "Delete",
Source: source,
}
// Start log
pl.SetLogInfo(&event, input, "started", "delete")
err = dg.I.Transaction(func(tx *gorm.DB) error {
pl.SetLogInfo(&event, rdDto, "started", "DBReadDetail")
data, err = ReadDetailData(rdDto, tx)
if err != nil {
return nil
event.Status = "failed"
event.ErrInfo = pl.ErrorInfo{
Code: "data-read-detail-fail",
Detail: "Database read detail failed",
Raw: err,
}
return pl.SetLogError(event, rdDto)
}
pl.SetLogInfo(&event, nil, "complete")
for i := range deletePreMw {
mwName := fmt.Sprintf("deletePreMw[%d]", i)
pl.SetLogInfo(&event, data, "started", mwName)
if err := deletePreMw[i](&rdDto, data, tx); err != nil {
return nil
event.Status = "failed"
event.ErrInfo = pl.ErrorInfo{
Code: "MW_PRE_FAILED", // TODO: add to lang json
Detail: fmt.Sprintf("Pre-middleware %s failed", mwName),
Raw: err,
}
return pl.SetLogError(event, data)
}
pl.SetLogInfo(&event, nil, "complete")
}
pl.SetLogInfo(&event, data, "started", "DBDelete")
if err := DeleteData(data, tx); err != nil {
return nil
}
for i := range deletePostMw {
if err := deletePostMw[i](&rdDto, data, tx); err != nil {
return nil
event.Status = "failed"
event.ErrInfo = pl.ErrorInfo{
Code: "data-delete-fail",
Detail: "Database delete failed",
Raw: err,
}
return pl.SetLogError(event, data)
}
pl.SetLogInfo(&event, nil, "complete")
for i := range deletePostMw {
mwName := fmt.Sprintf("deletePostMw[%d]", i)
pl.SetLogInfo(&event, data, "started", mwName)
if err := deletePostMw[i](&rdDto, data, tx); err != nil {
event.Status = "failed"
event.ErrInfo = pl.ErrorInfo{
Code: "MW_POST_FAILED", // TODO: add to lang json
Detail: fmt.Sprintf("Post-middleware %s failed", mwName),
Raw: err,
}
return pl.SetLogError(event, data)
}
pl.SetLogInfo(&event, nil, "complete")
}
return nil
})
+1 -1
View File
@@ -43,7 +43,7 @@ func ReadListData(input e.ReadListDto, dbx ...*gorm.DB) ([]e.User, *e.MetaDto, e
Scopes(gh.Filter(input)).
Count(&count).
Scopes(gh.Paginate(input, &pagination)).
Order("CreatedAt DESC")
Order("\"CreatedAt\" DESC")
if err := tx.Debug().Find(&data).Error; err != nil {
if err == gorm.ErrRecordNotFound {
+13 -2
View File
@@ -27,13 +27,24 @@ type ErrorInfo struct {
Raw error
}
func SetLogInfo(e Event, data any) {
// SetLogInfo updates the event and logs it.
// The first argument is the event, the second is the data.
// Variadic arguments:
// - first (optional): status
// - second (optional): action
func SetLogInfo(e *Event, data any, args ...string) {
dataString, _ := json.Marshal(data)
if len(args) > 0 {
e.Status = args[0]
}
if len(args) > 1 {
e.Action = args[1]
}
lz.O.Info().
String("source", e.Source).
String("feature", e.Feature).
String("action", e.Action).
String("status", "started").
String("status", e.Status).
String("input", string(dataString)).
Send()
}