diff --git a/.gitignore b/.gitignore
index 1b60356be050fb90cf748eff56bd32764627d2f7..8846f37d175c053007ac8dee5e513c8b7b2b6256 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,8 +1,19 @@
+# Swap files
+*.swp
+
 # Toolchain
-# Goland project folder
+# Golang project folder
 .idea/
+
 # Visual Studio Code
 .vscode/
+
+# Build
+bin/
+log/
+vendor/
+public/
+
 # emacs/vim
 GPATH
 GRTAGS
@@ -10,13 +21,10 @@ GTAGS
 TAGS
 tags
 cscope.*
-# mac
+
+# macOS
 .DS_Store
 
-# debug
+# Debug
 *.log
 *.pcap
-
-# build
-bin/
-public/
diff --git a/.golangci.yml b/.golangci.yml
index fbb3db5fa53fa635ecdbc522c51471a3e9c224cb..d358e43d7a56f9d0597bd497bc7508c635304f6c 100644
--- a/.golangci.yml
+++ b/.golangci.yml
@@ -30,11 +30,6 @@ run:
   # on Windows.
   skip-files:
     - "api_.*\\.go$"
-    - "model_.*\\.go$"
-    - "routers.go"
-    - "client.go"
-    - "configuration.go"
-    - "nas.go"
   # by default isn't set. If set we pass it to "go list -mod={option}". From "go help modules":
   # If invoked with -mod=readonly, the go command is disallowed from the implicit
   # automatic updating of go.mod described above. Instead, it fails when any changes
@@ -249,13 +244,14 @@ linters:
     # Additional
     - lll
     - godox
-    #- gomnd
-    #- goconst
+    # - gomnd
+    # - goconst
     # - gocognit
     # - maligned
     # - nestif
     # - gomodguard
     - nakedret
+    # - golint
     - gci
     - misspell
     - gofumpt
@@ -266,9 +262,9 @@ linters:
     - dogsled
     - bodyclose
     - asciicheck
-      #- stylecheck
-      # - unparam
-      # - wsl
+    # - stylecheck
+    # - unparam
+    # - wsl
 
   #disable-all: false
   fast: true
diff --git a/LICENSE.txt b/LICENSE
similarity index 100%
rename from LICENSE.txt
rename to LICENSE
diff --git a/backend/WebUI/api_webui.go b/backend/WebUI/api_webui.go
index 41b77b8a95575915ac925549a5e5699dbcf30727..8d1b24bed123ca6f7e695d8998bc94cf4d503957 100644
--- a/backend/WebUI/api_webui.go
+++ b/backend/WebUI/api_webui.go
@@ -10,15 +10,15 @@ import (
 	"strings"
 	"time"
 
-	"github.com/dgrijalva/jwt-go"
 	"github.com/gin-gonic/gin"
+	"github.com/golang-jwt/jwt"
 	"github.com/google/uuid"
 	"github.com/pkg/errors"
 	"go.mongodb.org/mongo-driver/bson"
 	"golang.org/x/crypto/bcrypt"
 
-	"github.com/free5gc/MongoDBLibrary"
 	"github.com/free5gc/openapi/models"
+	"github.com/free5gc/util/mongoapi"
 	"github.com/free5gc/webconsole/backend/logger"
 	"github.com/free5gc/webconsole/backend/webui_context"
 )
@@ -91,7 +91,10 @@ func sendResponseToClient(c *gin.Context, response *http.Response) {
 func sendResponseToClientFilterTenant(c *gin.Context, response *http.Response, tenantId string) {
 	// Subscription data.
 	filterTenantIdOnly := bson.M{"tenantId": tenantId}
-	amDataList := MongoDBLibrary.RestfulAPIGetMany(amDataColl, filterTenantIdOnly)
+	amDataList, err := mongoapi.RestfulAPIGetMany(amDataColl, filterTenantIdOnly)
+	if err != nil {
+		logger.WebUILog.Errorf("sendResponseToClientFilterTenant err: %+v", err)
+	}
 
 	tenantCheck := func(supi string) bool {
 		for _, amData := range amDataList {
@@ -366,7 +369,10 @@ func Login(c *gin.Context) {
 	generateHash(login.Password)
 
 	filterEmail := bson.M{"email": login.Username}
-	userData := MongoDBLibrary.RestfulAPIGetOne(userDataColl, filterEmail)
+	userData, err := mongoapi.RestfulAPIGetOne(userDataColl, filterEmail)
+	if err != nil {
+		logger.WebUILog.Errorf("Login err: %+v", err)
+	}
 
 	if len(userData) == 0 {
 		logger.WebUILog.Warnln("Can't find user email", login.Username)
@@ -457,7 +463,10 @@ func GetTenants(c *gin.Context) {
 		return
 	}
 
-	tenantDataInterface := MongoDBLibrary.RestfulAPIGetMany(tenantDataColl, bson.M{})
+	tenantDataInterface, err := mongoapi.RestfulAPIGetMany(tenantDataColl, bson.M{})
+	if err != nil {
+		logger.WebUILog.Errorf("GetTenants err: %+v", err)
+	}
 	var tenantData []Tenant
 	json.Unmarshal(sliceToByte(tenantDataInterface), &tenantData)
 
@@ -475,7 +484,10 @@ func GetTenantByID(c *gin.Context) {
 	tenantId := c.Param("tenantId")
 
 	filterTenantIdOnly := bson.M{"tenantId": tenantId}
-	tenantDataInterface := MongoDBLibrary.RestfulAPIGetOne(tenantDataColl, filterTenantIdOnly)
+	tenantDataInterface, err := mongoapi.RestfulAPIGetOne(tenantDataColl, filterTenantIdOnly)
+	if err != nil {
+		logger.WebUILog.Errorf("GetTenantByID err: %+v", err)
+	}
 	if len(tenantDataInterface) == 0 {
 		c.JSON(http.StatusNotFound, bson.M{})
 		return
@@ -507,7 +519,9 @@ func PostTenant(c *gin.Context) {
 
 	tenantBsonM := toBsonM(tenantData)
 	filterTenantIdOnly := bson.M{"tenantId": tenantData.TenantId}
-	MongoDBLibrary.RestfulAPIPost(tenantDataColl, filterTenantIdOnly, tenantBsonM)
+	if _, err := mongoapi.RestfulAPIPost(tenantDataColl, filterTenantIdOnly, tenantBsonM); err != nil {
+		logger.WebUILog.Errorf("PostTenant err: %+v", err)
+	}
 
 	c.JSON(http.StatusOK, tenantData)
 }
@@ -523,7 +537,10 @@ func PutTenantByID(c *gin.Context) {
 	tenantId := c.Param("tenantId")
 
 	filterTenantIdOnly := bson.M{"tenantId": tenantId}
-	tenantDataInterface := MongoDBLibrary.RestfulAPIGetOne(tenantDataColl, filterTenantIdOnly)
+	tenantDataInterface, err := mongoapi.RestfulAPIGetOne(tenantDataColl, filterTenantIdOnly)
+	if err != nil {
+		logger.WebUILog.Errorf("PutTenantByID err: %+v", err)
+	}
 	if len(tenantDataInterface) == 0 {
 		c.JSON(http.StatusNotFound, bson.M{})
 		return
@@ -538,7 +555,9 @@ func PutTenantByID(c *gin.Context) {
 
 	tenantBsonM := toBsonM(tenantData)
 	filterTenantIdOnly = bson.M{"tenantId": tenantId}
-	MongoDBLibrary.RestfulAPIPost(tenantDataColl, filterTenantIdOnly, tenantBsonM)
+	if _, err := mongoapi.RestfulAPIPost(tenantDataColl, filterTenantIdOnly, tenantBsonM); err != nil {
+		logger.WebUILog.Errorf("PutTenantByID err: %+v", err)
+	}
 
 	c.JSON(http.StatusOK, gin.H{})
 }
@@ -554,9 +573,15 @@ func DeleteTenantByID(c *gin.Context) {
 	tenantId := c.Param("tenantId")
 	filterTenantIdOnly := bson.M{"tenantId": tenantId}
 
-	MongoDBLibrary.RestfulAPIDeleteMany(amDataColl, filterTenantIdOnly)
-	MongoDBLibrary.RestfulAPIDeleteMany(userDataColl, filterTenantIdOnly)
-	MongoDBLibrary.RestfulAPIDeleteOne(tenantDataColl, filterTenantIdOnly)
+	if err := mongoapi.RestfulAPIDeleteMany(amDataColl, filterTenantIdOnly); err != nil {
+		logger.WebUILog.Errorf("DeleteTenantByID err: %+v", err)
+	}
+	if err := mongoapi.RestfulAPIDeleteMany(userDataColl, filterTenantIdOnly); err != nil {
+		logger.WebUILog.Errorf("DeleteTenantByID err: %+v", err)
+	}
+	if err := mongoapi.RestfulAPIDeleteOne(tenantDataColl, filterTenantIdOnly); err != nil {
+		logger.WebUILog.Errorf("DeleteTenantByID err: %+v", err)
+	}
 
 	c.JSON(http.StatusOK, gin.H{})
 }
@@ -564,7 +589,12 @@ func DeleteTenantByID(c *gin.Context) {
 // Utility function.
 func GetTenantById(tenantId string) map[string]interface{} {
 	filterTenantIdOnly := bson.M{"tenantId": tenantId}
-	return MongoDBLibrary.RestfulAPIGetOne(tenantDataColl, filterTenantIdOnly)
+	tenantData, err := mongoapi.RestfulAPIGetOne(tenantDataColl, filterTenantIdOnly)
+	if err != nil {
+		logger.WebUILog.Errorf("GetTenantById err: %+v", err)
+		return nil
+	}
+	return tenantData
 }
 
 // Users
@@ -583,7 +613,10 @@ func GetUsers(c *gin.Context) {
 	}
 
 	filterTenantIdOnly := bson.M{"tenantId": tenantId}
-	userDataInterface := MongoDBLibrary.RestfulAPIGetMany(userDataColl, filterTenantIdOnly)
+	userDataInterface, err := mongoapi.RestfulAPIGetMany(userDataColl, filterTenantIdOnly)
+	if err != nil {
+		logger.WebUILog.Errorf("GetUsers err: %+v", err)
+	}
 
 	var userData []User
 	json.Unmarshal(sliceToByte(userDataInterface), &userData)
@@ -610,7 +643,10 @@ func GetUserByID(c *gin.Context) {
 	userId := c.Param("userId")
 
 	filterUserIdOnly := bson.M{"tenantId": tenantId, "userId": userId}
-	userDataInterface := MongoDBLibrary.RestfulAPIGetOne(userDataColl, filterUserIdOnly)
+	userDataInterface, err := mongoapi.RestfulAPIGetOne(userDataColl, filterUserIdOnly)
+	if err != nil {
+		logger.WebUILog.Errorf("GetUserByID err: %+v", err)
+	}
 	if len(userDataInterface) == 0 {
 		c.JSON(http.StatusNotFound, bson.M{})
 		return
@@ -644,7 +680,10 @@ func PostUserByID(c *gin.Context) {
 	}
 
 	filterEmail := bson.M{"email": userData.Email}
-	userWithEmailData := MongoDBLibrary.RestfulAPIGetOne(userDataColl, filterEmail)
+	userWithEmailData, err := mongoapi.RestfulAPIGetOne(userDataColl, filterEmail)
+	if err != nil {
+		logger.WebUILog.Errorf("PostUserByID err: %+v", err)
+	}
 	if len(userWithEmailData) != 0 {
 		logger.WebUILog.Warnln("Email already exists", userData.Email)
 		c.JSON(http.StatusForbidden, gin.H{})
@@ -658,7 +697,9 @@ func PostUserByID(c *gin.Context) {
 
 	userBsonM := toBsonM(userData)
 	filterUserIdOnly := bson.M{"tenantId": userData.TenantId, "userId": userData.UserId}
-	MongoDBLibrary.RestfulAPIPost(userDataColl, filterUserIdOnly, userBsonM)
+	if _, err := mongoapi.RestfulAPIPost(userDataColl, filterUserIdOnly, userBsonM); err != nil {
+		logger.WebUILog.Errorf("PostUserByID err: %+v", err)
+	}
 
 	c.JSON(http.StatusOK, userData)
 }
@@ -685,7 +726,10 @@ func PutUserByID(c *gin.Context) {
 	}
 
 	filterUserIdOnly := bson.M{"tenantId": tenantId, "userId": userId}
-	userDataInterface := MongoDBLibrary.RestfulAPIGetOne(userDataColl, filterUserIdOnly)
+	userDataInterface, err := mongoapi.RestfulAPIGetOne(userDataColl, filterUserIdOnly)
+	if err != nil {
+		logger.WebUILog.Errorf("PutUserByID err: %+v", err)
+	}
 	if len(userDataInterface) == 0 {
 		c.JSON(http.StatusNotFound, bson.M{})
 		return
@@ -696,7 +740,10 @@ func PutUserByID(c *gin.Context) {
 
 	if newUserData.Email != "" && newUserData.Email != userData.Email {
 		filterEmail := bson.M{"email": newUserData.Email}
-		sameEmailInterface := MongoDBLibrary.RestfulAPIGetOne(userDataColl, filterEmail)
+		sameEmailInterface, err := mongoapi.RestfulAPIGetOne(userDataColl, filterEmail)
+		if err != nil {
+			logger.WebUILog.Errorf("PutUserByID err: %+v", err)
+		}
 		if len(sameEmailInterface) != 0 {
 			c.JSON(http.StatusBadRequest, bson.M{})
 			return
@@ -710,7 +757,9 @@ func PutUserByID(c *gin.Context) {
 	}
 
 	userBsonM := toBsonM(userData)
-	MongoDBLibrary.RestfulAPIPost(userDataColl, filterUserIdOnly, userBsonM)
+	if _, err := mongoapi.RestfulAPIPost(userDataColl, filterUserIdOnly, userBsonM); err != nil {
+		logger.WebUILog.Errorf("PutUserByID err: %+v", err)
+	}
 
 	c.JSON(http.StatusOK, userData)
 }
@@ -731,7 +780,9 @@ func DeleteUserByID(c *gin.Context) {
 	userId := c.Param("userId")
 
 	filterUserIdOnly := bson.M{"tenantId": tenantId, "userId": userId}
-	MongoDBLibrary.RestfulAPIDeleteOne(userDataColl, filterUserIdOnly)
+	if err := mongoapi.RestfulAPIDeleteOne(userDataColl, filterUserIdOnly); err != nil {
+		logger.WebUILog.Errorf("DeleteUserByID err: %+v", err)
+	}
 
 	c.JSON(http.StatusOK, gin.H{})
 }
@@ -758,14 +809,20 @@ func GetSubscribers(c *gin.Context) {
 	}
 
 	var subsList []SubsListIE = make([]SubsListIE, 0)
-	amDataList := MongoDBLibrary.RestfulAPIGetMany(amDataColl, bson.M{})
+	amDataList, err := mongoapi.RestfulAPIGetMany(amDataColl, bson.M{})
+	if err != nil {
+		logger.WebUILog.Errorf("GetSubscribers err: %+v", err)
+	}
 	for _, amData := range amDataList {
 		ueId := amData["ueId"]
 		servingPlmnId := amData["servingPlmnId"]
 		tenantId := amData["tenantId"]
 
 		filterUeIdOnly := bson.M{"ueId": ueId}
-		authSubsDataInterface := MongoDBLibrary.RestfulAPIGetOne(authSubsDataColl, filterUeIdOnly)
+		authSubsDataInterface, err := mongoapi.RestfulAPIGetOne(authSubsDataColl, filterUeIdOnly)
+		if err != nil {
+			logger.WebUILog.Errorf("GetSubscribers err: %+v", err)
+		}
 
 		var authSubsData AuthSub
 		json.Unmarshal(mapToByte(authSubsDataInterface), &authSubsData)
@@ -795,13 +852,34 @@ func GetSubscriberByID(c *gin.Context) {
 	filterUeIdOnly := bson.M{"ueId": ueId}
 	filter := bson.M{"ueId": ueId, "servingPlmnId": servingPlmnId}
 
-	authSubsDataInterface := MongoDBLibrary.RestfulAPIGetOne(authSubsDataColl, filterUeIdOnly)
-	amDataDataInterface := MongoDBLibrary.RestfulAPIGetOne(amDataColl, filter)
-	smDataDataInterface := MongoDBLibrary.RestfulAPIGetMany(smDataColl, filter)
-	smfSelDataInterface := MongoDBLibrary.RestfulAPIGetOne(smfSelDataColl, filter)
-	amPolicyDataInterface := MongoDBLibrary.RestfulAPIGetOne(amPolicyDataColl, filterUeIdOnly)
-	smPolicyDataInterface := MongoDBLibrary.RestfulAPIGetOne(smPolicyDataColl, filterUeIdOnly)
-	flowRuleDataInterface := MongoDBLibrary.RestfulAPIGetMany(flowRuleDataColl, filter)
+	authSubsDataInterface, err := mongoapi.RestfulAPIGetOne(authSubsDataColl, filterUeIdOnly)
+	if err != nil {
+		logger.WebUILog.Errorf("GetSubscriberByID err: %+v", err)
+	}
+	amDataDataInterface, err := mongoapi.RestfulAPIGetOne(amDataColl, filter)
+	if err != nil {
+		logger.WebUILog.Errorf("GetSubscriberByID err: %+v", err)
+	}
+	smDataDataInterface, err := mongoapi.RestfulAPIGetMany(smDataColl, filter)
+	if err != nil {
+		logger.WebUILog.Errorf("GetSubscriberByID err: %+v", err)
+	}
+	smfSelDataInterface, err := mongoapi.RestfulAPIGetOne(smfSelDataColl, filter)
+	if err != nil {
+		logger.WebUILog.Errorf("GetSubscriberByID err: %+v", err)
+	}
+	amPolicyDataInterface, err := mongoapi.RestfulAPIGetOne(amPolicyDataColl, filterUeIdOnly)
+	if err != nil {
+		logger.WebUILog.Errorf("GetSubscriberByID err: %+v", err)
+	}
+	smPolicyDataInterface, err := mongoapi.RestfulAPIGetOne(smPolicyDataColl, filterUeIdOnly)
+	if err != nil {
+		logger.WebUILog.Errorf("GetSubscriberByID err: %+v", err)
+	}
+	flowRuleDataInterface, err := mongoapi.RestfulAPIGetMany(flowRuleDataColl, filter)
+	if err != nil {
+		logger.WebUILog.Errorf("GetSubscriberByID err: %+v", err)
+	}
 
 	var authSubsData models.AuthenticationSubscription
 	json.Unmarshal(mapToByte(authSubsDataInterface), &authSubsData)
@@ -880,7 +958,10 @@ func PostSubscriberByID(c *gin.Context) {
 
 	// Lookup same UE ID of other tenant's subscription.
 	if claims != nil {
-		authSubsDataInterface := MongoDBLibrary.RestfulAPIGetOne(authSubsDataColl, filterUeIdOnly)
+		authSubsDataInterface, err := mongoapi.RestfulAPIGetOne(authSubsDataColl, filterUeIdOnly)
+		if err != nil {
+			logger.WebUILog.Errorf("PostSubscriberByID err: %+v", err)
+		}
 		if len(authSubsDataInterface) > 0 {
 			if authSubsDataInterface["tenantId"].(string) != claims["tenantId"].(string) {
 				c.JSON(http.StatusUnprocessableEntity, gin.H{})
@@ -935,13 +1016,27 @@ func PostSubscriberByID(c *gin.Context) {
 		flowRulesBsonA = append(flowRulesBsonA, flowRuleBsonM)
 	}
 
-	MongoDBLibrary.RestfulAPIPost(authSubsDataColl, filterUeIdOnly, authSubsBsonM)
-	MongoDBLibrary.RestfulAPIPost(amDataColl, filter, amDataBsonM)
-	MongoDBLibrary.RestfulAPIPostMany(smDataColl, filter, smDatasBsonA)
-	MongoDBLibrary.RestfulAPIPost(smfSelDataColl, filter, smfSelSubsBsonM)
-	MongoDBLibrary.RestfulAPIPost(amPolicyDataColl, filterUeIdOnly, amPolicyDataBsonM)
-	MongoDBLibrary.RestfulAPIPost(smPolicyDataColl, filterUeIdOnly, smPolicyDataBsonM)
-	MongoDBLibrary.RestfulAPIPostMany(flowRuleDataColl, filter, flowRulesBsonA)
+	if _, err := mongoapi.RestfulAPIPost(authSubsDataColl, filterUeIdOnly, authSubsBsonM); err != nil {
+		logger.WebUILog.Errorf("PostSubscriberByID err: %+v", err)
+	}
+	if _, err := mongoapi.RestfulAPIPost(amDataColl, filter, amDataBsonM); err != nil {
+		logger.WebUILog.Errorf("PostSubscriberByID err: %+v", err)
+	}
+	if err := mongoapi.RestfulAPIPostMany(smDataColl, filter, smDatasBsonA); err != nil {
+		logger.WebUILog.Errorf("PostSubscriberByID err: %+v", err)
+	}
+	if _, err := mongoapi.RestfulAPIPost(smfSelDataColl, filter, smfSelSubsBsonM); err != nil {
+		logger.WebUILog.Errorf("PostSubscriberByID err: %+v", err)
+	}
+	if _, err := mongoapi.RestfulAPIPost(amPolicyDataColl, filterUeIdOnly, amPolicyDataBsonM); err != nil {
+		logger.WebUILog.Errorf("PostSubscriberByID err: %+v", err)
+	}
+	if _, err := mongoapi.RestfulAPIPost(smPolicyDataColl, filterUeIdOnly, smPolicyDataBsonM); err != nil {
+		logger.WebUILog.Errorf("PostSubscriberByID err: %+v", err)
+	}
+	if err := mongoapi.RestfulAPIPostMany(flowRuleDataColl, filter, flowRulesBsonA); err != nil {
+		logger.WebUILog.Errorf("PostSubscriberByID err: %+v", err)
+	}
 
 	c.JSON(http.StatusCreated, gin.H{})
 }
@@ -973,13 +1068,17 @@ func PutSubscriberByID(c *gin.Context) {
 	amDataBsonM["servingPlmnId"] = servingPlmnId
 
 	// Replace all data with new one
-	MongoDBLibrary.RestfulAPIDeleteMany(smDataColl, filter)
+	if err := mongoapi.RestfulAPIDeleteMany(smDataColl, filter); err != nil {
+		logger.WebUILog.Errorf("PutSubscriberByID err: %+v", err)
+	}
 	for _, data := range subsData.SessionManagementSubscriptionData {
 		smDataBsonM := toBsonM(data)
 		smDataBsonM["ueId"] = ueId
 		smDataBsonM["servingPlmnId"] = servingPlmnId
 		filterSmData := bson.M{"ueId": ueId, "servingPlmnId": servingPlmnId, "snssai": data.SingleNssai}
-		MongoDBLibrary.RestfulAPIPutOne(smDataColl, filterSmData, smDataBsonM)
+		if _, err := mongoapi.RestfulAPIPutOne(smDataColl, filterSmData, smDataBsonM); err != nil {
+			logger.WebUILog.Errorf("PutSubscriberByID err: %+v", err)
+		}
 	}
 
 	for key, SnssaiData := range subsData.SmPolicyData.SmPolicySnssaiData {
@@ -1008,14 +1107,28 @@ func PutSubscriberByID(c *gin.Context) {
 		flowRulesBsonA = append(flowRulesBsonA, flowRuleBsonM)
 	}
 	// Replace all data with new one
-	MongoDBLibrary.RestfulAPIDeleteMany(flowRuleDataColl, filter)
-	MongoDBLibrary.RestfulAPIPostMany(flowRuleDataColl, filter, flowRulesBsonA)
+	if err := mongoapi.RestfulAPIDeleteMany(flowRuleDataColl, filter); err != nil {
+		logger.WebUILog.Errorf("PutSubscriberByID err: %+v", err)
+	}
+	if err := mongoapi.RestfulAPIPostMany(flowRuleDataColl, filter, flowRulesBsonA); err != nil {
+		logger.WebUILog.Errorf("PutSubscriberByID err: %+v", err)
+	}
 
-	MongoDBLibrary.RestfulAPIPutOne(authSubsDataColl, filterUeIdOnly, authSubsBsonM)
-	MongoDBLibrary.RestfulAPIPutOne(amDataColl, filter, amDataBsonM)
-	MongoDBLibrary.RestfulAPIPutOne(smfSelDataColl, filter, smfSelSubsBsonM)
-	MongoDBLibrary.RestfulAPIPutOne(amPolicyDataColl, filterUeIdOnly, amPolicyDataBsonM)
-	MongoDBLibrary.RestfulAPIPutOne(smPolicyDataColl, filterUeIdOnly, smPolicyDataBsonM)
+	if _, err := mongoapi.RestfulAPIPutOne(authSubsDataColl, filterUeIdOnly, authSubsBsonM); err != nil {
+		logger.WebUILog.Errorf("PutSubscriberByID err: %+v", err)
+	}
+	if _, err := mongoapi.RestfulAPIPutOne(amDataColl, filter, amDataBsonM); err != nil {
+		logger.WebUILog.Errorf("PutSubscriberByID err: %+v", err)
+	}
+	if _, err := mongoapi.RestfulAPIPutOne(smfSelDataColl, filter, smfSelSubsBsonM); err != nil {
+		logger.WebUILog.Errorf("PutSubscriberByID err: %+v", err)
+	}
+	if _, err := mongoapi.RestfulAPIPutOne(amPolicyDataColl, filterUeIdOnly, amPolicyDataBsonM); err != nil {
+		logger.WebUILog.Errorf("PutSubscriberByID err: %+v", err)
+	}
+	if _, err := mongoapi.RestfulAPIPutOne(smPolicyDataColl, filterUeIdOnly, smPolicyDataBsonM); err != nil {
+		logger.WebUILog.Errorf("PutSubscriberByID err: %+v", err)
+	}
 
 	c.JSON(http.StatusNoContent, gin.H{})
 }
@@ -1047,13 +1160,17 @@ func PatchSubscriberByID(c *gin.Context) {
 	amDataBsonM["servingPlmnId"] = servingPlmnId
 
 	// Replace all data with new one
-	MongoDBLibrary.RestfulAPIDeleteMany(smDataColl, filter)
+	if err := mongoapi.RestfulAPIDeleteMany(smDataColl, filter); err != nil {
+		logger.WebUILog.Errorf("PatchSubscriberByID err: %+v", err)
+	}
 	for _, data := range subsData.SessionManagementSubscriptionData {
 		smDataBsonM := toBsonM(data)
 		smDataBsonM["ueId"] = ueId
 		smDataBsonM["servingPlmnId"] = servingPlmnId
 		filterSmData := bson.M{"ueId": ueId, "servingPlmnId": servingPlmnId, "snssai": data.SingleNssai}
-		MongoDBLibrary.RestfulAPIMergePatch(smDataColl, filterSmData, smDataBsonM)
+		if err := mongoapi.RestfulAPIMergePatch(smDataColl, filterSmData, smDataBsonM); err != nil {
+			logger.WebUILog.Errorf("PatchSubscriberByID err: %+v", err)
+		}
 	}
 
 	for key, SnssaiData := range subsData.SmPolicyData.SmPolicySnssaiData {
@@ -1074,11 +1191,21 @@ func PatchSubscriberByID(c *gin.Context) {
 	smPolicyDataBsonM := toBsonM(subsData.SmPolicyData)
 	smPolicyDataBsonM["ueId"] = ueId
 
-	MongoDBLibrary.RestfulAPIMergePatch(authSubsDataColl, filterUeIdOnly, authSubsBsonM)
-	MongoDBLibrary.RestfulAPIMergePatch(amDataColl, filter, amDataBsonM)
-	MongoDBLibrary.RestfulAPIMergePatch(smfSelDataColl, filter, smfSelSubsBsonM)
-	MongoDBLibrary.RestfulAPIMergePatch(amPolicyDataColl, filterUeIdOnly, amPolicyDataBsonM)
-	MongoDBLibrary.RestfulAPIMergePatch(smPolicyDataColl, filterUeIdOnly, smPolicyDataBsonM)
+	if err := mongoapi.RestfulAPIMergePatch(authSubsDataColl, filterUeIdOnly, authSubsBsonM); err != nil {
+		logger.WebUILog.Errorf("PatchSubscriberByID err: %+v", err)
+	}
+	if err := mongoapi.RestfulAPIMergePatch(amDataColl, filter, amDataBsonM); err != nil {
+		logger.WebUILog.Errorf("PatchSubscriberByID err: %+v", err)
+	}
+	if err := mongoapi.RestfulAPIMergePatch(smfSelDataColl, filter, smfSelSubsBsonM); err != nil {
+		logger.WebUILog.Errorf("PatchSubscriberByID err: %+v", err)
+	}
+	if err := mongoapi.RestfulAPIMergePatch(amPolicyDataColl, filterUeIdOnly, amPolicyDataBsonM); err != nil {
+		logger.WebUILog.Errorf("PatchSubscriberByID err: %+v", err)
+	}
+	if err := mongoapi.RestfulAPIMergePatch(smPolicyDataColl, filterUeIdOnly, smPolicyDataBsonM); err != nil {
+		logger.WebUILog.Errorf("PatchSubscriberByID err: %+v", err)
+	}
 
 	c.JSON(http.StatusNoContent, gin.H{})
 }
@@ -1094,13 +1221,27 @@ func DeleteSubscriberByID(c *gin.Context) {
 	filterUeIdOnly := bson.M{"ueId": ueId}
 	filter := bson.M{"ueId": ueId, "servingPlmnId": servingPlmnId}
 
-	MongoDBLibrary.RestfulAPIDeleteOne(authSubsDataColl, filterUeIdOnly)
-	MongoDBLibrary.RestfulAPIDeleteOne(amDataColl, filter)
-	MongoDBLibrary.RestfulAPIDeleteMany(smDataColl, filter)
-	MongoDBLibrary.RestfulAPIDeleteMany(flowRuleDataColl, filter)
-	MongoDBLibrary.RestfulAPIDeleteOne(smfSelDataColl, filter)
-	MongoDBLibrary.RestfulAPIDeleteOne(amPolicyDataColl, filterUeIdOnly)
-	MongoDBLibrary.RestfulAPIDeleteOne(smPolicyDataColl, filterUeIdOnly)
+	if err := mongoapi.RestfulAPIDeleteOne(authSubsDataColl, filterUeIdOnly); err != nil {
+		logger.WebUILog.Errorf("DeleteSubscriberByID err: %+v", err)
+	}
+	if err := mongoapi.RestfulAPIDeleteOne(amDataColl, filter); err != nil {
+		logger.WebUILog.Errorf("DeleteSubscriberByID err: %+v", err)
+	}
+	if err := mongoapi.RestfulAPIDeleteMany(smDataColl, filter); err != nil {
+		logger.WebUILog.Errorf("DeleteSubscriberByID err: %+v", err)
+	}
+	if err := mongoapi.RestfulAPIDeleteMany(flowRuleDataColl, filter); err != nil {
+		logger.WebUILog.Errorf("DeleteSubscriberByID err: %+v", err)
+	}
+	if err := mongoapi.RestfulAPIDeleteOne(smfSelDataColl, filter); err != nil {
+		logger.WebUILog.Errorf("DeleteSubscriberByID err: %+v", err)
+	}
+	if err := mongoapi.RestfulAPIDeleteOne(amPolicyDataColl, filterUeIdOnly); err != nil {
+		logger.WebUILog.Errorf("DeleteSubscriberByID err: %+v", err)
+	}
+	if err := mongoapi.RestfulAPIDeleteOne(smPolicyDataColl, filterUeIdOnly); err != nil {
+		logger.WebUILog.Errorf("DeleteSubscriberByID err: %+v", err)
+	}
 
 	c.JSON(http.StatusNoContent, gin.H{})
 }
diff --git a/backend/WebUI/routers.go b/backend/WebUI/routers.go
index 1bed2554781287d9f1392d1e36f5161c5c367316..226b0a36d755a30676ec0d95964db2a796438f48 100644
--- a/backend/WebUI/routers.go
+++ b/backend/WebUI/routers.go
@@ -5,7 +5,7 @@ import (
 
 	"github.com/gin-gonic/gin"
 
-	"github.com/free5gc/logger_util"
+	logger_util "github.com/free5gc/util/logger"
 	"github.com/free5gc/webconsole/backend/logger"
 )
 
diff --git a/backend/factory/config.go b/backend/factory/config.go
index 662bd9c090de43706fe1c60e7ef095410f73697f..8ddbe2124dc845e8df3eb2bc71b0a1bc7f193149 100644
--- a/backend/factory/config.go
+++ b/backend/factory/config.go
@@ -7,7 +7,7 @@
 package factory
 
 import (
-	"github.com/free5gc/logger_util"
+	logger_util "github.com/free5gc/util/logger"
 )
 
 type Config struct {
diff --git a/backend/logger/logger.go b/backend/logger/logger.go
index 720a896ff1ce8e6e0598d83dd69911591f12268a..124363f54264c7be0671594398101eea8d6a96f8 100644
--- a/backend/logger/logger.go
+++ b/backend/logger/logger.go
@@ -7,8 +7,7 @@ import (
 	formatter "github.com/antonfisher/nested-logrus-formatter"
 	"github.com/sirupsen/logrus"
 
-	"github.com/free5gc/logger_conf"
-	"github.com/free5gc/logger_util"
+	logger_util "github.com/free5gc/util/logger"
 )
 
 var (
@@ -32,17 +31,6 @@ func init() {
 		FieldsOrder:     []string{"component", "category"},
 	}
 
-	free5gcLogHook, err := logger_util.NewFileHook(logger_conf.Free5gcLogFile, os.O_CREATE|os.O_APPEND|os.O_RDWR, 0o666)
-	if err == nil {
-		log.Hooks.Add(free5gcLogHook)
-	}
-
-	selfLogHook, err := logger_util.NewFileHook(
-		logger_conf.Free5gcLogDir+"webconsole.log", os.O_CREATE|os.O_APPEND|os.O_RDWR, 0o666)
-	if err == nil {
-		log.Hooks.Add(selfLogHook)
-	}
-
 	AppLog = log.WithFields(logrus.Fields{"component": "WebUI", "category": "App"})
 	InitLog = log.WithFields(logrus.Fields{"component": "WebUI", "category": "Init"})
 	WebUILog = log.WithFields(logrus.Fields{"component": "WebUI", "category": "WebUI"})
@@ -50,10 +38,36 @@ func init() {
 	GinLog = log.WithFields(logrus.Fields{"component": "WebUI", "category": "GIN"})
 }
 
+func LogFileHook(logNfPath string, log5gcPath string) error {
+	if fullPath, err := logger_util.CreateFree5gcLogFile(log5gcPath); err == nil {
+		if fullPath != "" {
+			free5gcLogHook, hookErr := logger_util.NewFileHook(fullPath, os.O_CREATE|os.O_APPEND|os.O_RDWR, 0o666)
+			if hookErr != nil {
+				return hookErr
+			}
+			log.Hooks.Add(free5gcLogHook)
+		}
+	} else {
+		return err
+	}
+
+	if fullPath, err := logger_util.CreateNfLogFile(logNfPath, "webconsole.log"); err == nil {
+		selfLogHook, hookErr := logger_util.NewFileHook(fullPath, os.O_CREATE|os.O_APPEND|os.O_RDWR, 0o666)
+		if hookErr != nil {
+			return hookErr
+		}
+		log.Hooks.Add(selfLogHook)
+	} else {
+		return err
+	}
+
+	return nil
+}
+
 func SetLogLevel(level logrus.Level) {
 	log.SetLevel(level)
 }
 
-func SetReportCaller(set bool) {
-	log.SetReportCaller(set)
+func SetReportCaller(enable bool) {
+	log.SetReportCaller(enable)
 }
diff --git a/backend/webui_context/context.go b/backend/webui_context/context.go
index a28121203c2de4a45d1f0f8287b89657b39dd014..00036ac7bb97fb2b942c757dc9d62fe13f492f47 100644
--- a/backend/webui_context/context.go
+++ b/backend/webui_context/context.go
@@ -2,13 +2,10 @@ package webui_context
 
 import (
 	"fmt"
-	"reflect"
-	"time"
 
-	"github.com/mitchellh/mapstructure"
-
-	"github.com/free5gc/MongoDBLibrary"
 	"github.com/free5gc/openapi/models"
+	timedecode "github.com/free5gc/util/mapstruct"
+	"github.com/free5gc/util/mongoapi"
 	"github.com/free5gc/webconsole/backend/logger"
 )
 
@@ -29,12 +26,16 @@ func init() {
 }
 
 func (context *WEBUIContext) UpdateNfProfiles() {
-	nfProfilesRaw := MongoDBLibrary.RestfulAPIGetMany("NfProfile", nil)
-	nfProfiles, err := decode(nfProfilesRaw, time.RFC3339)
+	nfProfilesRaw, err := mongoapi.RestfulAPIGetMany("NfProfile", nil)
 	if err != nil {
 		logger.ContextLog.Error(err)
 		return
 	}
+	var nfProfiles []models.NfProfile
+	if err := timedecode.Decode(nfProfilesRaw, &nfProfiles); err != nil {
+		logger.ContextLog.Error(err)
+		return
+	}
 
 	context.NFProfiles = nfProfiles
 
@@ -108,39 +109,6 @@ func WEBUI_Self() *WEBUIContext {
 	return &webuiContext
 }
 
-// Copy from lib/TimeDecode/TimeDecode.go
-func decode(source interface{}, format string) ([]models.NfProfile, error) {
-	var target []models.NfProfile
-
-	// config mapstruct
-	stringToDateTimeHook := func(
-		f reflect.Type,
-		t reflect.Type,
-		data interface{}) (interface{}, error) {
-		if t == reflect.TypeOf(time.Time{}) && f == reflect.TypeOf("") {
-			return time.Parse(format, data.(string))
-		}
-		return data, nil
-	}
-
-	config := mapstructure.DecoderConfig{
-		DecodeHook: stringToDateTimeHook,
-		Result:     &target,
-	}
-
-	decoder, err := mapstructure.NewDecoder(&config)
-	if err != nil {
-		return nil, err
-	}
-
-	// Decode result to NfProfile structure
-	err = decoder.Decode(source)
-	if err != nil {
-		return nil, err
-	}
-	return target, nil
-}
-
 func getSbiUri(scheme models.UriScheme, ipv4Address string, port int32) (uri string) {
 	if port != 0 {
 		uri = fmt.Sprintf("%s://%s:%d", scheme, ipv4Address, port)
diff --git a/backend/webui_service/middleware.go b/backend/webui_service/middleware.go
index 0f42b31bacddbe9effe26b6cb7690928ea6478ec..b4f2107d9623567bac6f6f0dd7a473a8289984f5 100644
--- a/backend/webui_service/middleware.go
+++ b/backend/webui_service/middleware.go
@@ -4,11 +4,7 @@ import (
 	"github.com/gin-gonic/gin"
 )
 
-var PublicPath string
-
-func init() {
-	PublicPath = "public"
-}
+var PublicPath = "public"
 
 func ReturnPublic() gin.HandlerFunc {
 	return func(context *gin.Context) {
diff --git a/backend/webui_service/webui_init.go b/backend/webui_service/webui_init.go
index 17c5d16b262e0126668cf6b34c8693a7ca9becc5..a69527e97f29bb870df94b2b1455f3ec10f1bda8 100644
--- a/backend/webui_service/webui_init.go
+++ b/backend/webui_service/webui_init.go
@@ -4,16 +4,15 @@ import (
 	"bufio"
 	"fmt"
 	"os/exec"
+	"path/filepath"
+	"runtime/debug"
 	"sync"
 
 	"github.com/gin-contrib/cors"
 	"github.com/sirupsen/logrus"
 	"github.com/urfave/cli"
 
-	"github.com/free5gc/MongoDBLibrary"
-	mongoDBLibLogger "github.com/free5gc/MongoDBLibrary/logger"
-	openApiLogger "github.com/free5gc/openapi/logger"
-	pathUtilLogger "github.com/free5gc/path_util/logger"
+	"github.com/free5gc/util/mongoapi"
 	"github.com/free5gc/webconsole/backend/WebUI"
 	"github.com/free5gc/webconsole/backend/factory"
 	"github.com/free5gc/webconsole/backend/logger"
@@ -23,51 +22,65 @@ import (
 type WEBUI struct{}
 
 type (
-	// Config information.
-	Config struct {
-		webuicfg string
+	// Commands information.
+	Commands struct {
+		config string
+		public string
 	}
 )
 
-var config Config
+var commands Commands
 
-var webuiCLi = []cli.Flag{
+var cliCmd = []cli.Flag{
 	cli.StringFlag{
-		Name:  "free5gccfg",
-		Usage: "common config file",
+		Name:  "public, p",
+		Usage: "Load public path from `FOLDER`",
 	},
 	cli.StringFlag{
-		Name:  "webuicfg",
-		Usage: "config file",
+		Name:  "config, c",
+		Usage: "Load configuration from `FILE`",
+	},
+	cli.StringFlag{
+		Name:  "log, l",
+		Usage: "Output NF log to `FILE`",
+	},
+	cli.StringFlag{
+		Name:  "log5gc, lc",
+		Usage: "Output free5gc log to `FILE`",
 	},
 }
 
 var initLog *logrus.Entry
 
-func init() {
-	initLog = logger.InitLog
-}
-
 func (*WEBUI) GetCliCmd() (flags []cli.Flag) {
-	return webuiCLi
+	return cliCmd
 }
 
-func (webui *WEBUI) Initialize(c *cli.Context) {
-	config = Config{
-		webuicfg: c.String("webuicfg"),
+func (webui *WEBUI) Initialize(c *cli.Context) error {
+	commands = Commands{
+		config: c.String("config"),
+		public: c.String("public"),
 	}
 
-	if config.webuicfg != "" {
-		if err := factory.InitConfigFactory(config.webuicfg); err != nil {
-			panic(err)
+	initLog = logger.InitLog
+
+	if commands.config != "" {
+		if err := factory.InitConfigFactory(commands.config); err != nil {
+			return err
 		}
 	} else {
 		if err := factory.InitConfigFactory("./config/webuicfg.yaml"); err != nil {
-			panic(err)
+			return err
 		}
 	}
 
+	if commands.public != "" {
+		PublicPath = filepath.Clean(commands.public)
+	}
+
 	webui.setLogLevel()
+
+	return nil
 }
 
 func (webui *WEBUI) setLogLevel() {
@@ -92,54 +105,6 @@ func (webui *WEBUI) setLogLevel() {
 		}
 		logger.SetReportCaller(factory.WebUIConfig.Logger.WEBUI.ReportCaller)
 	}
-
-	if factory.WebUIConfig.Logger.PathUtil != nil {
-		if factory.WebUIConfig.Logger.PathUtil.DebugLevel != "" {
-			if level, err := logrus.ParseLevel(factory.WebUIConfig.Logger.PathUtil.DebugLevel); err != nil {
-				pathUtilLogger.PathLog.Warnf("PathUtil Log level [%s] is invalid, set to [info] level",
-					factory.WebUIConfig.Logger.PathUtil.DebugLevel)
-				pathUtilLogger.SetLogLevel(logrus.InfoLevel)
-			} else {
-				pathUtilLogger.SetLogLevel(level)
-			}
-		} else {
-			pathUtilLogger.PathLog.Warnln("PathUtil Log level not set. Default set to [info] level")
-			pathUtilLogger.SetLogLevel(logrus.InfoLevel)
-		}
-		pathUtilLogger.SetReportCaller(factory.WebUIConfig.Logger.PathUtil.ReportCaller)
-	}
-
-	if factory.WebUIConfig.Logger.OpenApi != nil {
-		if factory.WebUIConfig.Logger.OpenApi.DebugLevel != "" {
-			if level, err := logrus.ParseLevel(factory.WebUIConfig.Logger.OpenApi.DebugLevel); err != nil {
-				openApiLogger.OpenApiLog.Warnf("OpenAPI Log level [%s] is invalid, set to [info] level",
-					factory.WebUIConfig.Logger.OpenApi.DebugLevel)
-				openApiLogger.SetLogLevel(logrus.InfoLevel)
-			} else {
-				openApiLogger.SetLogLevel(level)
-			}
-		} else {
-			openApiLogger.OpenApiLog.Warnln("OpenAPI Log level not set. Default set to [info] level")
-			openApiLogger.SetLogLevel(logrus.InfoLevel)
-		}
-		openApiLogger.SetReportCaller(factory.WebUIConfig.Logger.OpenApi.ReportCaller)
-	}
-
-	if factory.WebUIConfig.Logger.MongoDBLibrary != nil {
-		if factory.WebUIConfig.Logger.MongoDBLibrary.DebugLevel != "" {
-			if level, err := logrus.ParseLevel(factory.WebUIConfig.Logger.MongoDBLibrary.DebugLevel); err != nil {
-				mongoDBLibLogger.MongoDBLog.Warnf("MongoDBLibrary Log level [%s] is invalid, set to [info] level",
-					factory.WebUIConfig.Logger.MongoDBLibrary.DebugLevel)
-				mongoDBLibLogger.SetLogLevel(logrus.InfoLevel)
-			} else {
-				mongoDBLibLogger.SetLogLevel(level)
-			}
-		} else {
-			mongoDBLibLogger.MongoDBLog.Warnln("MongoDBLibrary Log level not set. Default set to [info] level")
-			mongoDBLibLogger.SetLogLevel(logrus.InfoLevel)
-		}
-		mongoDBLibLogger.SetReportCaller(factory.WebUIConfig.Logger.MongoDBLibrary.ReportCaller)
-	}
 }
 
 func (webui *WEBUI) FilterCli(c *cli.Context) (args []string) {
@@ -160,7 +125,10 @@ func (webui *WEBUI) Start() {
 	mongodb := factory.WebUIConfig.Configuration.Mongodb
 
 	// Connect to MongoDB
-	MongoDBLibrary.SetMongoDB(mongodb.Name, mongodb.Url)
+	if err := mongoapi.SetMongoDB(mongodb.Name, mongodb.Url); err != nil {
+		initLog.Errorf("Server start err: %+v", err)
+		return
+	}
 
 	initLog.Infoln("Server started")
 
@@ -192,7 +160,9 @@ func (webui *WEBUI) Exec(c *cli.Context) error {
 	initLog.Traceln("filter: ", args)
 	command := exec.Command("./webui", args...)
 
-	webui.Initialize(c)
+	if err := webui.Initialize(c); err != nil {
+		return err
+	}
 
 	stdout, err := command.StdoutPipe()
 	if err != nil {
@@ -201,6 +171,13 @@ func (webui *WEBUI) Exec(c *cli.Context) error {
 	wg := sync.WaitGroup{}
 	wg.Add(3)
 	go func() {
+		defer func() {
+			if p := recover(); p != nil {
+				// Print stack for panic to log. Fatalf() will let program exit.
+				logger.InitLog.Fatalf("panic: %v\n%s", p, string(debug.Stack()))
+			}
+		}()
+
 		in := bufio.NewScanner(stdout)
 		for in.Scan() {
 			fmt.Println(in.Text())
@@ -213,6 +190,13 @@ func (webui *WEBUI) Exec(c *cli.Context) error {
 		initLog.Fatalln(err)
 	}
 	go func() {
+		defer func() {
+			if p := recover(); p != nil {
+				// Print stack for panic to log. Fatalf() will let program exit.
+				logger.InitLog.Fatalf("panic: %v\n%s", p, string(debug.Stack()))
+			}
+		}()
+
 		in := bufio.NewScanner(stderr)
 		for in.Scan() {
 			fmt.Println(in.Text())
@@ -221,6 +205,13 @@ func (webui *WEBUI) Exec(c *cli.Context) error {
 	}()
 
 	go func() {
+		defer func() {
+			if p := recover(); p != nil {
+				// Print stack for panic to log. Fatalf() will let program exit.
+				logger.InitLog.Fatalf("panic: %v\n%s", p, string(debug.Stack()))
+			}
+		}()
+
 		if errCmd := command.Start(); errCmd != nil {
 			fmt.Println("command.Start Fails!")
 		}
diff --git a/config/webuicfg.yaml b/config/webuicfg.yaml
index 0eb418e2676b113bc7e03b96d567a01b130f6b49..f837ab769f3a6330a93db10cbfb308eddb411efa 100644
--- a/config/webuicfg.yaml
+++ b/config/webuicfg.yaml
@@ -3,23 +3,14 @@ info:
   description: WebUI initial local configuration
 
 configuration:
-  mongodb:                          # the mongodb connected by this webui
-    name: free5gc                   # name of the mongodb
-    url: mongodb://localhost:27017  # a valid URL of the mongodb
+  mongodb: # the mongodb connected by this webui
+    name: free5gc # name of the mongodb
+    url: mongodb://localhost:27017 # a valid URL of the mongodb
 
 # the kind of log output
 # debugLevel: how detailed to output, value: trace, debug, info, warn, error, fatal, panic
 # ReportCaller: enable the caller report or not, value: true or false
 logger:
   WEBUI:
-    debugLevel: info
-    ReportCaller: true
-  PathUtil:
-    debugLevel: info
-    ReportCaller: false
-  OpenApi:
-    debugLevel: info
-    ReportCaller: false
-  MongoDBLibrary:
     debugLevel: info
     ReportCaller: false
diff --git a/go.mod b/go.mod
index ea381cc149f7ed63d1c40b7472d118eec8c92c52..6af20191f33507fa3383617d1c2c615501124c52 100644
--- a/go.mod
+++ b/go.mod
@@ -3,22 +3,17 @@ module github.com/free5gc/webconsole
 go 1.14
 
 require (
-	github.com/antonfisher/nested-logrus-formatter v1.3.0
-	github.com/dgrijalva/jwt-go v3.2.0+incompatible
-	github.com/free5gc/MongoDBLibrary v1.0.0
-	github.com/free5gc/logger_conf v1.0.0
-	github.com/free5gc/logger_util v1.0.0
-	github.com/free5gc/openapi v1.0.0
-	github.com/free5gc/path_util v1.0.0
-	github.com/free5gc/version v1.0.0
+	github.com/antonfisher/nested-logrus-formatter v1.3.1
+	github.com/free5gc/openapi v1.0.4
+	github.com/free5gc/util v1.0.1
 	github.com/gin-contrib/cors v1.3.1
-	github.com/gin-gonic/gin v1.6.3
+	github.com/gin-gonic/gin v1.7.3
+	github.com/golang-jwt/jwt v3.2.1+incompatible
 	github.com/google/uuid v1.3.0
-	github.com/mitchellh/mapstructure v1.4.0
 	github.com/pkg/errors v0.9.1
-	github.com/sirupsen/logrus v1.7.0
+	github.com/sirupsen/logrus v1.8.1
 	github.com/urfave/cli v1.22.5
-	go.mongodb.org/mongo-driver v1.4.4
+	go.mongodb.org/mongo-driver v1.7.1
 	golang.org/x/crypto v0.0.0-20201208171446-5f87f3452ae9
 	gopkg.in/yaml.v2 v2.4.0
 )
diff --git a/go.sum b/go.sum
index a789e8bfe64e7056273c947f9ce0b3283a6dd3d7..585880a5d7a3cd41249af275c2396a83dc584253 100644
--- a/go.sum
+++ b/go.sum
@@ -34,11 +34,10 @@ dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7
 github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
 github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
 github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
-github.com/antonfisher/nested-logrus-formatter v1.3.0 h1:8zixYquU1Odk+vzAaAQPAdRh1ZjmUXNQ1T+dUBvlhVo=
-github.com/antonfisher/nested-logrus-formatter v1.3.0/go.mod h1:6WTfyWFkBc9+zyBaKIqRrg/KwMqBbodBjgbHjDz7zjA=
-github.com/aws/aws-sdk-go v1.34.28/go.mod h1:H7NKnBqNVzoTJpGfLrQkkD+ytBA93eiDYi/+8rV9s48=
-github.com/aws/aws-sdk-go v1.36.7 h1:XoJPAjKoqvdL531XGWxKYn5eGX/xMoXzMN5fBtoyfSY=
-github.com/aws/aws-sdk-go v1.36.7/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro=
+github.com/antonfisher/nested-logrus-formatter v1.3.1 h1:NFJIr+pzwv5QLHTPyKz9UMEoHck02Q9L0FP13b/xSbQ=
+github.com/antonfisher/nested-logrus-formatter v1.3.1/go.mod h1:6WTfyWFkBc9+zyBaKIqRrg/KwMqBbodBjgbHjDz7zjA=
+github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d h1:Byv0BzEl3/e6D5CLfI0j/7hiIEtvGVFPCZ7Ei2oq8iQ=
+github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
 github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
 github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
 github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
@@ -50,34 +49,23 @@ github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:ma
 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
 github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
-github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
-github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
 github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
 github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
 github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
 github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
-github.com/evanphx/json-patch v4.9.0+incompatible h1:kLcOMZeuLAJvL2BPWLMIj5oaZQobrkAqrL+WFZwQses=
-github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
-github.com/free5gc/MongoDBLibrary v1.0.0 h1:+CN5t3G9AvI4iv7azq46KUK4VWYsprbR7OHBqVM9XSo=
-github.com/free5gc/MongoDBLibrary v1.0.0/go.mod h1:0TSgWaO+5KyIrylML6jbHqtgoJJKpHGiXHPFdHXXPts=
-github.com/free5gc/http2_util v1.0.0/go.mod h1:GN2BCD8IINjtnAKYGwe+dEeTBRFEv4lQnZblFIIhbdE=
-github.com/free5gc/logger_conf v1.0.0 h1:cMqqB8L4HjE57tP36mBmiVUPIcHv8Ayr12jKfeiwqZU=
-github.com/free5gc/logger_conf v1.0.0/go.mod h1:DHecLXVV1qA5Z+lSoUvZdZ6tCtZidTNmtx99jsCfgLE=
-github.com/free5gc/logger_util v1.0.0 h1:hLTCTnKlEqJURrBwooNFQLavWPdJzS0o9KGIYUNKdJI=
-github.com/free5gc/logger_util v1.0.0/go.mod h1:TK/bAJbm/l2TMNmbsKn83+xUmDNqts69IEir/nCa8w0=
-github.com/free5gc/openapi v1.0.0 h1:DaGVt05b1pSDBOailKAlLj6hAk6vunN0Nhzvl/xcWCY=
-github.com/free5gc/openapi v1.0.0/go.mod h1:7OzxoWBj6KQgznMW2ZiUtZdCGY+t89v4wtgKLhluKgU=
-github.com/free5gc/path_util v1.0.0 h1:vJPGTymaWtavz6fJ/7k6WKEYv5BQLAq/O04RP54sab0=
-github.com/free5gc/path_util v1.0.0/go.mod h1:OpmcebEKrMPnH7Jg5lZ8y9ZWJNAjQ4l9FGWXUv58Mo0=
-github.com/free5gc/version v1.0.0 h1:Kn4uOhyHT1IAgerBgWRHag4xLMDXrRsqubLeMv5Nb/w=
-github.com/free5gc/version v1.0.0/go.mod h1:wOTwzjk7sqeysX1b/Z4x+pWBHFuZOPtQj3h+IJXSpmQ=
+github.com/evanphx/json-patch v0.5.2 h1:xVCHIVMUu1wtM/VkR9jVZ45N3FhZfYMMYGorLCR8P3k=
+github.com/evanphx/json-patch v0.5.2/go.mod h1:ZWS5hhDbVDyob71nXKNL0+PWn6ToqBHMikGIFbs31qQ=
+github.com/free5gc/openapi v1.0.4 h1:bC6oqXy8Z+3e532xLMFmrTHvdyv4sNGDPezQSslw5gQ=
+github.com/free5gc/openapi v1.0.4/go.mod h1:KRCnnp0GeK0Bl4gnrX79cQAidKXNENf8VRdG0y9R0Fc=
+github.com/free5gc/util v1.0.1 h1:A8bynjzZXkYMLOq9FN5J4Yg5mdjXhYoXc/FFFwSLPss=
+github.com/free5gc/util v1.0.1/go.mod h1:VsA8FaZAxZW6eKzF/VXN2kuctl19Tj+NYH7ZxkZ+YCA=
 github.com/gin-contrib/cors v1.3.1 h1:doAsuITavI4IOcd0Y19U4B+O0dNWihRyX//nn4sEmgA=
 github.com/gin-contrib/cors v1.3.1/go.mod h1:jjEJ4268OPZUcU7k9Pm653S7lXUGcqMADzFA61xsmDk=
 github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
 github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
 github.com/gin-gonic/gin v1.5.0/go.mod h1:Nd6IXA8m5kNZdNEHMBd93KT+mdY3+bewLgRvmCsR2Do=
-github.com/gin-gonic/gin v1.6.3 h1:ahKqKTFpO5KTPHxWZjEdPScmYaGtLo8Y4DMHoEsnp14=
-github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M=
+github.com/gin-gonic/gin v1.7.3 h1:aMBzLJ/GMEYmv1UWs2FFTcPISLrQH2mRgL9Glz8xows=
+github.com/gin-gonic/gin v1.7.3/go.mod h1:jD2toBW3GZUr5UMcdrwQA10I7RuaFOl/SGeDjXkfUtY=
 github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
 github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
 github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
@@ -89,10 +77,8 @@ github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTM
 github.com/go-playground/universal-translator v0.16.0/go.mod h1:1AnU7NaIRDWWzGEKwgtJRd2xk99HeFyHw3yid4rvQIY=
 github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no=
 github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA=
-github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI=
 github.com/go-playground/validator/v10 v10.4.1 h1:pH2c5ADXtd66mxoE0Zm9SUhxE20r7aM3F26W0hOn+GE=
 github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4=
-github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
 github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk=
 github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
 github.com/gobuffalo/attrs v0.0.0-20190224210810-a9411de4debd/go.mod h1:4duuawTqi2wkkpB4ePgWMaai6/Kc6WEz83bhFwpHzj0=
@@ -119,6 +105,8 @@ github.com/gobuffalo/packd v0.1.0/go.mod h1:M2Juc+hhDXf/PnmBANFCqx4DM3wRbgDvnVWe
 github.com/gobuffalo/packr/v2 v2.0.9/go.mod h1:emmyGweYTm6Kdper+iywB6YK5YzuKchGtJQZ0Odn4pQ=
 github.com/gobuffalo/packr/v2 v2.2.0/go.mod h1:CaAwI0GPIAv+5wKLtv8Afwl+Cm78K/I/VCm/3ptBN+0=
 github.com/gobuffalo/syncx v0.0.0-20190224160051-33c29581e754/go.mod h1:HhnNqWY95UYwwW3uSASeV7vtgYkT2t16hJgV3AEPUpw=
+github.com/golang-jwt/jwt v3.2.1+incompatible h1:73Z+4BJcrTC+KczS6WvTPvRGOp1WmfEP4Q1lOd9Z/+c=
+github.com/golang-jwt/jwt v3.2.1+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
 github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
 github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
 github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
@@ -142,12 +130,10 @@ github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrU
 github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
 github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
 github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
+github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0=
 github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
-github.com/golang/protobuf v1.4.3 h1:JjCZWpVbqXDqFVmTfYWEVTMIYrL/NPdPSCHPJ0T/raM=
-github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
+github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4=
 github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
-github.com/golang/snappy v0.0.2 h1:aeE13tS0IiQgFjYdoL8qN3K1N2bXXtI6Vi51/y7BpMw=
-github.com/golang/snappy v0.0.2/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
 github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
 github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
 github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
@@ -174,28 +160,27 @@ github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
 github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
 github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
 github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
+github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
+github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
 github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542/go.mod h1:Ow0tF8D4Kplbc8s8sSb3V2oUCygFHVp8gC3Dn6U4MNI=
 github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
 github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
 github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
 github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
-github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg=
-github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
-github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8=
-github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
+github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
 github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg=
 github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
+github.com/json-iterator/go v1.1.9 h1:9yzud/Ht36ygwatGx56VwCZtlI/2AD15T1X2sjSuGns=
 github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
-github.com/json-iterator/go v1.1.10 h1:Kz6Cvnvv2wGdaG/V8yMvfkmNiXq9Ya2KUv4rouJJr68=
-github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
 github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
 github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
+github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
+github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
 github.com/karrick/godirwalk v1.8.0/go.mod h1:H5KPZjojv4lE+QYImBI8xVtrBRgYrIVsaRPx4tDPEn4=
 github.com/karrick/godirwalk v1.10.3/go.mod h1:RoGL9dQei4vP9ilrpETWE8CLOZ1kiN0LhBygSwrAsHA=
 github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
+github.com/klauspost/compress v1.9.5 h1:U+CaK85mrNNb4k8BNOfgJtJ/gr6kswUCFj6miSzVC6M=
 github.com/klauspost/compress v1.9.5/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
-github.com/klauspost/compress v1.11.3 h1:dB4Bn0tN3wdCzQxnS8r06kV74qN/TAfaIS0bVE8h3jc=
-github.com/klauspost/compress v1.11.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
 github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
 github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
 github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
@@ -211,14 +196,12 @@ github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kN
 github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ=
 github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
 github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
-github.com/mitchellh/mapstructure v1.4.0 h1:7ks8ZkOP5/ujthUsT07rNv+nkLXCQWKNHuwzOAesEks=
-github.com/mitchellh/mapstructure v1.4.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
+github.com/mitchellh/mapstructure v1.4.1 h1:CpVNEelQCZBooIPDn+AR3NpivK/TIKU8bDxdASFVQag=
+github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
+github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc=
 github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
-github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
-github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
+github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742 h1:Esafd1046DLDQ0W1YjYsBW+p8U2u7vzgW2SQVmlNazg=
 github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
-github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI=
-github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
 github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc=
 github.com/nbio/st v0.0.0-20140626010706-e9e8d9816f32/go.mod h1:9wM+0iRr9ahx58uYLpLIr5fm8diHn0JbqRycJi6w0Ms=
 github.com/pelletier/go-toml v1.7.0/go.mod h1:vwGMzjaWMwyfHwgIBhI2YUM4fB6nL6lVAvS1LBMMhTE=
@@ -239,8 +222,12 @@ github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeV
 github.com/sirupsen/logrus v1.4.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
 github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
 github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
-github.com/sirupsen/logrus v1.7.0 h1:ShrD1U9pZB12TX0cVy0DtePoCH97K8EtX+mg7ZARUtM=
-github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
+github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE=
+github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
+github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
+github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
+github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s=
+github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
 github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
 github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
 github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
@@ -248,27 +235,30 @@ github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
 github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
 github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
 github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
-github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
 github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
+github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
 github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4=
 github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
+github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo=
 github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw=
-github.com/ugorji/go v1.2.1 h1:dz+JxTe7GZQdErTo7SREc1jQj/hFP1k7jyIAwODoW+k=
-github.com/ugorji/go v1.2.1/go.mod h1:cSVypSfTLm2o9fKxXvQgn3rMmkPXovcWor6Qn5tbFmI=
+github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs=
 github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY=
-github.com/ugorji/go/codec v1.2.1 h1:/TRfW3XKkvWvmAYyCUaQlhoCDGjcvNR8xVVA/l5p/jQ=
-github.com/ugorji/go/codec v1.2.1/go.mod h1:s/WxCRi46t8rA+fowL40EnmD7ec0XhR7ZypxeBNdzsM=
 github.com/urfave/cli v1.22.5 h1:lNq9sAHXK2qfdI8W+GRItjCEkI+2oR4d+MEHy1CKXoU=
 github.com/urfave/cli v1.22.5/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
-github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c h1:u40Z8hqBAAQyv+vATcGgV0YCnDjqSL7/q/JyPhhJSPk=
-github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I=
-github.com/xdg/stringprep v0.0.0-20180714160509-73f8eece6fdc h1:n+nNi93yXLkJvKwXNP9d55HC7lGK4H/SRcwB5IaUZLo=
-github.com/xdg/stringprep v0.0.0-20180714160509-73f8eece6fdc/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y=
+github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c=
+github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
+github.com/xdg-go/scram v1.0.2 h1:akYIkZ28e6A96dkWNJQu3nmCzH3YfwMPQExUYDaRv7w=
+github.com/xdg-go/scram v1.0.2/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+hCSs=
+github.com/xdg-go/stringprep v1.0.2 h1:6iq84/ryjjeRmMJwxutI51F2GIPlP5BfTvXHeYjyhBc=
+github.com/xdg-go/stringprep v1.0.2/go.mod h1:8F9zXuvzgwmyT5DUm4GUfZGDdT3W+LCvS6+da4O5kxM=
+github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d h1:splanxYIlg+5LfHAM6xpdFEAYOk8iySO56hMFq6uLyA=
+github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA=
 github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
 github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
 github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
-go.mongodb.org/mongo-driver v1.4.4 h1:bsPHfODES+/yx2PCWzUYMH8xj6PVniPI8DQrsJuSXSs=
-go.mongodb.org/mongo-driver v1.4.4/go.mod h1:WcMNYLx/IlOxLe6JRJiv2uXuCz6zBLndR4SoGjYphSc=
+go.mongodb.org/mongo-driver v1.7.1 h1:jwqTeEM3x6L9xDXrCxN0Hbg7vdGfPBOTIkr0+/LYZDA=
+go.mongodb.org/mongo-driver v1.7.1/go.mod h1:Q4oFMbo1+MSNqICAdYMlC/zSTrwCogR4R8NzkI+yfU8=
 go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
 go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
 go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
@@ -278,9 +268,9 @@ golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnf
 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
 golang.org/x/crypto v0.0.0-20190422162423-af44ce270edf/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
 golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
-golang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
 golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
 golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
 golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
 golang.org/x/crypto v0.0.0-20201208171446-5f87f3452ae9 h1:sYNJzB4J8toYPQTM6pAkcmBRgw9SnQKP9oXCHfgy604=
 golang.org/x/crypto v0.0.0-20201208171446-5f87f3452ae9/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
@@ -326,7 +316,6 @@ golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR
 golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.0.0-20191021144547-ec77196f6094/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
@@ -341,15 +330,13 @@ golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/
 golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
 golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
 golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
-golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
-golang.org/x/net v0.0.0-20201209123823-ac852fbbde11 h1:lwlPPsmjDKK0J6eG6xDWd5XPehI0R024zxjDnw3esPA=
-golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
+golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
 golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
 golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
 golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
 golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
 golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
-golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
+golang.org/x/oauth2 v0.0.0-20210810183815-faf39c7919d5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
 golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -358,9 +345,8 @@ golang.org/x/sync v0.0.0-20190412183630-56d357773e84/go.mod h1:RxMgew5VJxzue5/jJ
 golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208 h1:qwRHBd0NqMbJxfbotnDhm2ByMI1Shq4Y6oRJo21SGJA=
 golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.0.0-20201207232520-09787c993a3a h1:DcqTD9SDLc+1P/r1EmRBwnVsrOwW+kk2vWf9n+1sGhs=
-golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -394,10 +380,9 @@ golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7w
 golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20201211090839-8ad439b19e0f h1:QdHQnPce6K4XQewki9WNbG5KOROuDzqO3NaYjI1cXJ0=
-golang.org/x/sys v0.0.0-20201211090839-8ad439b19e0f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210423082822-04245dca01da h1:b3NXsE2LusjYGGjL5bxEVZZORm/YEFFrWFjR8eFrw/c=
+golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
 golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -405,8 +390,9 @@ golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
 golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
-golang.org/x/text v0.3.4 h1:0YWbFKbhXG/wIiuHDSKpS0Iy7FSA+u45VtBMfQcFTTc=
-golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M=
+golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
@@ -416,6 +402,7 @@ golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3
 golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
 golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
 golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
 golang.org/x/tools v0.0.0-20190329151228-23e29df326fe/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
 golang.org/x/tools v0.0.0-20190416151739-9c9e1878f421/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
 golang.org/x/tools v0.0.0-20190420181800-aa740d480789/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
@@ -481,7 +468,6 @@ google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7
 google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
 google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
 google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
-google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
 google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
 google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
 google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
@@ -540,8 +526,7 @@ gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8
 gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
 gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE=
 gopkg.in/go-playground/validator.v9 v9.29.1/go.mod h1:+c9/zcJMFNgbLvly1L1V+PpxWdVbfP1avr/N00E2vyQ=
-gopkg.in/h2non/gentleman.v1 v1.0.4/go.mod h1:JYuHVdFzS4MKOXe0o+chKJ4hCe6tqKKw9XH9YP6WFrg=
-gopkg.in/h2non/gock.v1 v1.0.16/go.mod h1:XVuDAssexPLwgxCLMvDTWNU5eqklsydR6I5phZ9oPB8=
+gopkg.in/h2non/gock.v1 v1.1.2/go.mod h1:n7UGz/ckNChHiK05rDoiC4MYSunEC/lyaUm2WWaDva0=
 gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
diff --git a/server.go b/server.go
index 21ca3cacb84a8ec462926ebad169edfc6c7dbcc6..51ebabd2861776c0e79a5855ca8f8da388a768a3 100644
--- a/server.go
+++ b/server.go
@@ -1,38 +1,50 @@
 package main
 
 import (
+	"fmt"
 	"os"
 
-	"github.com/sirupsen/logrus"
 	"github.com/urfave/cli"
 
-	"github.com/free5gc/version"
+	"github.com/free5gc/util/version"
 	"github.com/free5gc/webconsole/backend/logger"
 	"github.com/free5gc/webconsole/backend/webui_service"
 )
 
 var WEBUI = &webui_service.WEBUI{}
 
-var appLog *logrus.Entry
-
-func init() {
-	appLog = logger.AppLog
-}
-
 func main() {
 	app := cli.NewApp()
 	app.Name = "webui"
-	appLog.Infoln(app.Name)
-	appLog.Infoln("webconsole version: ", version.GetVersion())
-	app.Usage = "-free5gccfg common configuration file -webuicfg webui configuration file"
+	app.Usage = "free5GC Web Console"
 	app.Action = action
 	app.Flags = WEBUI.GetCliCmd()
 	if err := app.Run(os.Args); err != nil {
-		logger.AppLog.Warnf("Error args: %v", err)
+		logger.AppLog.Errorf("Web Console Run error: %v", err)
 	}
 }
 
-func action(c *cli.Context) {
-	WEBUI.Initialize(c)
+func action(c *cli.Context) error {
+	if err := initLogFile(c.String("log"), c.String("log5gc")); err != nil {
+		logger.AppLog.Errorf("%+v", err)
+		return err
+	}
+
+	if err := WEBUI.Initialize(c); err != nil {
+		return fmt.Errorf("Failed to initialize !! %+v", err)
+	}
+
+	logger.AppLog.Infoln(c.App.Name)
+	logger.AppLog.Infoln("webconsole version: ", version.GetVersion())
+
 	WEBUI.Start()
+
+	return nil
+}
+
+func initLogFile(logNfPath, log5gcPath string) error {
+	if err := logger.LogFileHook(logNfPath, log5gcPath); err != nil {
+		return err
+	}
+	return nil
 }