Skip to content

Commit

Permalink
Merge pull request #17 from spotlibs/feat/enhancement-middleware-acti…
Browse files Browse the repository at this point in the history
…vity-monitor

feat: enhancement middleware activity monitor
  • Loading branch information
mdanialr authored Sep 29, 2024
2 parents a3cd483 + 2a6c12c commit 8933031
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 11 deletions.
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,9 @@ Reusable go library that mostly implement standardization in the scope of Spotli
Currently, pkg that are already considered has stable API are
- `stderr`: standard interface for any error that may occur in the Spotlibs Team Microservices
- `stdresp`: standard interface to construct standard response
- `validation`: helper to validate request for `Goravel` framework
- `validation`: ease validating request for `Goravel` framework
- `debug`: capture stack trace
- `middleware`: consist of some useful and important predefined middlewares
- `activity monitor`: capture and log all incoming & outgoing http request/response. Can properly record request body with content-type `application/json`, `application/x-www-form-urlencoded` & `multipart/form-data`
- `metadata header`: set `http.Context` with metadata information coming from the request header
- `recover`: do recover on panic that occur during processing request in `Goravel` with properly giving back appropriate `stdresp`
45 changes: 35 additions & 10 deletions middleware/activity_monitor.go
Original file line number Diff line number Diff line change
@@ -1,17 +1,26 @@
package middleware

import (
"mime/multipart"
"slices"
"strings"
"time"

"github.com/bytedance/sonic"
"github.com/goravel/framework/contracts/http"
"github.com/goravel/framework/facades"
"github.com/goravel/framework/filesystem"
"github.com/spotlibs/go-lib/ctx"
"github.com/spotlibs/go-lib/log"
)

// formDataFile holds information of each binary file in multipart form-data.
type formDataFile struct {
Filename string `json:"filename"`
Mimetype string `json:"mimetype"`
Size int `json:"size"`
}

// ActivityMonitor capture and log all request/response.
func ActivityMonitor(c http.Context) {
now := time.Now()
Expand Down Expand Up @@ -69,30 +78,32 @@ func captureRequestMap(c http.Context) any {
}

// captureRequestMultipart capture request multipart data and only get
// the information of that file such as the filename, size and extension.
// the information of each file such as the filename, size and extension.
// Include key-val form data but only pick the first value for each key.
func captureRequestMultipart(c http.Context) any {
reqOrg := c.Request().Origin()
_ = reqOrg.ParseMultipartForm(2 << 9) // 1024

var bagOfForm []map[string]any
bagOfForm := make(map[string]any)
// grab any available form-value
for k, v := range reqOrg.MultipartForm.Value {
bagOfForm = append(bagOfForm, map[string]any{
"field": k,
"value": v,
})
if len(v) > 0 {
bagOfForm[k] = v[0] // only pick the first data
}
}
// grab any available files
for field, header := range reqOrg.MultipartForm.File {
var bagFormFiles []formDataFile
for _, headerFile := range header {
if headerFile != nil {
bagOfForm = append(bagOfForm, map[string]any{
"field": field,
"filename": headerFile.Filename,
"size": int(headerFile.Size),
bagFormFiles = append(bagFormFiles, formDataFile{
Filename: headerFile.Filename,
Size: int(headerFile.Size),
Mimetype: sniffMIMEType(headerFile),
})
}
}
bagOfForm[field] = bagFormFiles
}

return bagOfForm
Expand All @@ -104,3 +115,17 @@ func hasPrefix(s string, prefix ...string) bool {
return strings.HasPrefix(s, pre)
})
}

// sniffMIMEType return the mime-type from given FileHeader instance by using
// helper provided by Goravel.
func sniffMIMEType(f *multipart.FileHeader) string {
fl, err := filesystem.NewFileFromRequest(f)
if err != nil {
return "ERR-" + err.Error()
}
mt, err := fl.MimeType()
if err != nil {
return "ERR-" + err.Error()
}
return mt
}

0 comments on commit 8933031

Please sign in to comment.