Implement custom logger with log levels

This commit is contained in:
Pijus Kamandulis 2024-02-27 22:38:59 +02:00
parent b9e38575bc
commit 6ccb7c4bdd
13 changed files with 108 additions and 51 deletions

View File

@ -51,6 +51,7 @@ To disable SSL and run Cosmium on HTTP instead, you can use the `-DisableTls` fl
* **-InitialData**: Path to JSON containing initial state
* **-Persist**: Saves data to the given path on application exit (When `-InitialData` argument is not supplied, it will try to load data from path supplied in `-Persist`)
* **-Port**: Listen port (default 8081)
* **-Debug**: Runs application in debug mode, this provides additional logging
These arguments allow you to configure various aspects of Cosmium's behavior according to your requirements.

View File

@ -22,6 +22,7 @@ func ParseFlags() {
disableAuthentication := flag.Bool("DisableAuth", false, "Disable authentication")
disableTls := flag.Bool("DisableTls", false, "Disable TLS, serve over HTTP")
persistDataPath := flag.String("Persist", "", "Saves data to given path on application exit")
debug := flag.Bool("Debug", false, "Runs application in debug mode, this provides additional logging")
flag.Parse()
@ -34,6 +35,7 @@ func ParseFlags() {
Config.PersistDataFilePath = *persistDataPath
Config.DisableAuth = *disableAuthentication
Config.DisableTls = *disableTls
Config.Debug = *debug
Config.DatabaseAccount = Config.Host
Config.DatabaseDomain = Config.Host

View File

@ -15,4 +15,5 @@ type ServerConfig struct {
PersistDataFilePath string
DisableAuth bool
DisableTls bool
Debug bool
}

View File

@ -1,13 +1,13 @@
package middleware
import (
"fmt"
"net/url"
"strings"
"github.com/gin-gonic/gin"
"github.com/pikami/cosmium/api/config"
"github.com/pikami/cosmium/internal/authentication"
"github.com/pikami/cosmium/internal/logger"
)
func Authentication() gin.HandlerFunc {
@ -53,7 +53,7 @@ func Authentication() gin.HandlerFunc {
params, _ := url.ParseQuery(decoded)
clientSignature := strings.Replace(params.Get("sig"), " ", "+", -1)
if clientSignature != expectedSignature {
fmt.Printf("Got wrong signature from client.\n- Expected: %s\n- Got: %s\n", expectedSignature, clientSignature)
logger.Errorf("Got wrong signature from client.\n- Expected: %s\n- Got: %s\n", expectedSignature, clientSignature)
c.IndentedJSON(401, gin.H{
"code": "Unauthorized",
"message": "Wrong signature.",

View File

@ -2,10 +2,10 @@ package middleware
import (
"bytes"
"fmt"
"io"
"github.com/gin-gonic/gin"
"github.com/pikami/cosmium/internal/logger"
)
func RequestLogger() gin.HandlerFunc {
@ -16,7 +16,7 @@ func RequestLogger() gin.HandlerFunc {
bodyStr := readBody(rdr1)
if bodyStr != "" {
fmt.Println(bodyStr)
logger.Debug(bodyStr)
}
c.Request.Body = rdr2

View File

@ -8,12 +8,17 @@ import (
"github.com/pikami/cosmium/api/config"
"github.com/pikami/cosmium/api/handlers"
"github.com/pikami/cosmium/api/handlers/middleware"
"github.com/pikami/cosmium/internal/logger"
tlsprovider "github.com/pikami/cosmium/internal/tls_provider"
)
func CreateRouter() *gin.Engine {
router := gin.Default()
if config.Config.Debug {
router.Use(middleware.RequestLogger())
}
router.Use(middleware.Authentication())
router.GET("/dbs/:databaseId/colls/:collId/pkranges", handlers.GetPartitionKeyRanges)
@ -49,6 +54,10 @@ func CreateRouter() *gin.Engine {
}
func StartAPI() {
if !config.Config.Debug {
gin.SetMode(gin.ReleaseMode)
}
router := CreateRouter()
listenAddress := fmt.Sprintf(":%d", config.Config.Port)
@ -58,7 +67,7 @@ func StartAPI() {
config.Config.TLS_CertificatePath,
config.Config.TLS_CertificateKey)
if err != nil {
fmt.Println("Failed to start HTTPS server:", err)
logger.Error("Failed to start HTTPS server:", err)
}
return
@ -68,17 +77,17 @@ func StartAPI() {
router.Run(listenAddress)
}
tlsConfig := config.GetDefaultTlsConfig()
tlsConfig := tlsprovider.GetDefaultTlsConfig()
server := &http.Server{
Addr: listenAddress,
Handler: router.Handler(),
TLSConfig: tlsConfig,
}
fmt.Printf("Listening and serving HTTPS on %s\n", server.Addr)
logger.Infof("Listening and serving HTTPS on %s\n", server.Addr)
err := server.ListenAndServeTLS("", "")
if err != nil {
fmt.Println("Failed to start HTTPS server:", err)
logger.Error("Failed to start HTTPS server:", err)
}
router.Run()

40
internal/logger/logger.go Normal file
View File

@ -0,0 +1,40 @@
package logger
import (
"log"
"os"
"github.com/pikami/cosmium/api/config"
)
var DebugLogger = log.New(os.Stdout, "", log.Ldate|log.Ltime|log.Lshortfile)
var InfoLogger = log.New(os.Stdout, "", log.Ldate|log.Ltime)
var ErrorLogger = log.New(os.Stderr, "", log.Ldate|log.Ltime|log.Lshortfile)
func Debug(v ...any) {
if config.Config.Debug {
DebugLogger.Println(v...)
}
}
func Debugf(format string, v ...any) {
if config.Config.Debug {
DebugLogger.Printf(format, v...)
}
}
func Info(v ...any) {
InfoLogger.Println(v...)
}
func Infof(format string, v ...any) {
InfoLogger.Printf(format, v...)
}
func Error(v ...any) {
ErrorLogger.Println(v...)
}
func Errorf(format string, v ...any) {
ErrorLogger.Printf(format, v...)
}

View File

@ -2,12 +2,12 @@ package repositories
import (
"encoding/json"
"fmt"
"log"
"os"
"reflect"
"github.com/pikami/cosmium/api/config"
"github.com/pikami/cosmium/internal/logger"
repositorymodels "github.com/pikami/cosmium/internal/repository_models"
)
@ -33,7 +33,7 @@ func InitializeRepository() {
}
if stat.IsDir() {
fmt.Println("Argument '-Persist' must be a path to file, not a directory.")
logger.Error("Argument '-Persist' must be a path to file, not a directory.")
os.Exit(1)
}
@ -55,10 +55,10 @@ func LoadStateFS(filePath string) {
return
}
fmt.Println("Loaded state:")
fmt.Printf("Databases: %d\n", getLength(state.Databases))
fmt.Printf("Collections: %d\n", getLength(state.Collections))
fmt.Printf("Documents: %d\n", getLength(state.Documents))
logger.Info("Loaded state:")
logger.Infof("Databases: %d\n", getLength(state.Databases))
logger.Infof("Collections: %d\n", getLength(state.Collections))
logger.Infof("Documents: %d\n", getLength(state.Documents))
storeState = state
@ -68,16 +68,16 @@ func LoadStateFS(filePath string) {
func SaveStateFS(filePath string) {
data, err := json.MarshalIndent(storeState, "", "\t")
if err != nil {
fmt.Printf("Failed to save state: %v\n", err)
logger.Errorf("Failed to save state: %v\n", err)
return
}
os.WriteFile(filePath, data, os.ModePerm)
fmt.Println("Saved state:")
fmt.Printf("Databases: %d\n", getLength(storeState.Databases))
fmt.Printf("Collections: %d\n", getLength(storeState.Collections))
fmt.Printf("Documents: %d\n", getLength(storeState.Documents))
logger.Info("Saved state:")
logger.Infof("Databases: %d\n", getLength(storeState.Databases))
logger.Infof("Collections: %d\n", getLength(storeState.Collections))
logger.Infof("Documents: %d\n", getLength(storeState.Documents))
}
func GetState() repositorymodels.State {

View File

@ -1,9 +1,4 @@
package config
import (
"crypto/tls"
"fmt"
)
package tlsprovider
const certificate = `
-----BEGIN CERTIFICATE-----
@ -64,15 +59,3 @@ ilcZlmaCS9pqIXAFK9GQ89V/xa8OibOuJUiBgShnfSQqAwQrfX1vYjtKErnjoRFs
9+zaWugLCC47Hw6QlMDa
-----END PRIVATE KEY-----
`
func GetDefaultTlsConfig() *tls.Config {
cert, err := tls.X509KeyPair([]byte(certificate), []byte(certificateKey))
if err != nil {
fmt.Println("Failed to parse certificate and key:", err)
return &tls.Config{}
}
return &tls.Config{
Certificates: []tls.Certificate{cert},
}
}

View File

@ -0,0 +1,19 @@
package tlsprovider
import (
"crypto/tls"
"github.com/pikami/cosmium/internal/logger"
)
func GetDefaultTlsConfig() *tls.Config {
cert, err := tls.X509KeyPair([]byte(certificate), []byte(certificateKey))
if err != nil {
logger.Error("Failed to parse certificate and key:", err)
return &tls.Config{}
}
return &tls.Config{
Certificates: []tls.Certificate{cert},
}
}

View File

@ -1,9 +1,9 @@
package memoryexecutor
import (
"fmt"
"reflect"
"github.com/pikami/cosmium/internal/logger"
"github.com/pikami/cosmium/parsers"
)
@ -36,13 +36,13 @@ func (c memoryExecutorContext) array_Slice(arguments []interface{}, row RowType)
lengthEx := c.getFieldValue(arguments[2].(parsers.SelectItem), row)
if length, ok = lengthEx.(int); !ok {
fmt.Println("array_Slice - got length parameters of wrong type")
logger.Error("array_Slice - got length parameters of wrong type")
return []interface{}{}
}
}
if start, ok = startEx.(int); !ok {
fmt.Println("array_Slice - got start parameters of wrong type")
logger.Error("array_Slice - got start parameters of wrong type")
return []interface{}{}
}
@ -117,7 +117,7 @@ func (c memoryExecutorContext) parseArray(argument interface{}, row RowType) []i
arrValue := reflect.ValueOf(ex)
if arrValue.Kind() != reflect.Slice {
fmt.Println("parseArray got parameters of wrong type")
logger.Error("parseArray got parameters of wrong type")
return nil
}

View File

@ -6,6 +6,7 @@ import (
"sort"
"strings"
"github.com/pikami/cosmium/internal/logger"
"github.com/pikami/cosmium/parsers"
)
@ -168,7 +169,7 @@ func (c memoryExecutorContext) getFieldValue(field parsers.SelectItem, row RowTy
var ok bool
if typedValue, ok = field.Value.(parsers.Constant); !ok {
// TODO: Handle error
fmt.Println("parsers.Constant has incorrect Value type")
logger.Error("parsers.Constant has incorrect Value type")
}
if typedValue.Type == parsers.ConstantTypeParameterConstant &&
@ -186,7 +187,7 @@ func (c memoryExecutorContext) getFieldValue(field parsers.SelectItem, row RowTy
var ok bool
if typedValue, ok = field.Value.(parsers.FunctionCall); !ok {
// TODO: Handle error
fmt.Println("parsers.Constant has incorrect Value type")
logger.Error("parsers.Constant has incorrect Value type")
}
switch typedValue.Type {
@ -288,7 +289,7 @@ func (c memoryExecutorContext) getExpressionParameterValue(
return c.getFieldValue(typedParameter, row)
}
fmt.Println("getExpressionParameterValue - got incorrect parameter type")
logger.Error("getExpressionParameterValue - got incorrect parameter type")
return nil
}

View File

@ -4,6 +4,7 @@ import (
"fmt"
"strings"
"github.com/pikami/cosmium/internal/logger"
"github.com/pikami/cosmium/parsers"
)
@ -118,7 +119,7 @@ func (c memoryExecutorContext) strings_Left(arguments []interface{}, row RowType
lengthEx := c.getFieldValue(arguments[1].(parsers.SelectItem), row)
if length, ok = lengthEx.(int); !ok {
fmt.Println("strings_Left - got parameters of wrong type")
logger.Error("strings_Left - got parameters of wrong type")
return ""
}
@ -157,7 +158,7 @@ func (c memoryExecutorContext) strings_Replicate(arguments []interface{}, row Ro
timesEx := c.getFieldValue(arguments[1].(parsers.SelectItem), row)
if times, ok = timesEx.(int); !ok {
fmt.Println("strings_Replicate - got parameters of wrong type")
logger.Error("strings_Replicate - got parameters of wrong type")
return ""
}
@ -190,7 +191,7 @@ func (c memoryExecutorContext) strings_Right(arguments []interface{}, row RowTyp
lengthEx := c.getFieldValue(arguments[1].(parsers.SelectItem), row)
if length, ok = lengthEx.(int); !ok {
fmt.Println("strings_Right - got parameters of wrong type")
logger.Error("strings_Right - got parameters of wrong type")
return ""
}
@ -219,11 +220,11 @@ func (c memoryExecutorContext) strings_Substring(arguments []interface{}, row Ro
lengthEx := c.getFieldValue(arguments[2].(parsers.SelectItem), row)
if startPos, ok = startPosEx.(int); !ok {
fmt.Println("strings_Substring - got start parameters of wrong type")
logger.Error("strings_Substring - got start parameters of wrong type")
return ""
}
if length, ok = lengthEx.(int); !ok {
fmt.Println("strings_Substring - got length parameters of wrong type")
logger.Error("strings_Substring - got length parameters of wrong type")
return ""
}
@ -263,7 +264,7 @@ func (c memoryExecutorContext) parseString(argument interface{}, row RowType) st
return str1
}
fmt.Println("StringEquals got parameters of wrong type")
logger.Error("StringEquals got parameters of wrong type")
return ""
}