From 56611f934026db97b7acc414251056d2168d3636 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Victor?= Date: Wed, 4 Dec 2024 19:56:33 -0300 Subject: [PATCH] feature: add elastic db - add suport to elastic db --- README.md | 26 ++++- README_en_us.md | 27 ++++- go.mod | 13 ++- go.sum | 16 +++ internal/database/dbhandler/handler.go | 26 +++-- internal/database/elastic/connect.go | 38 +++++++ internal/database/elastic/functions.go | 91 +++++++++++++++ internal/services/savelogs.go | 47 ++++++-- testMain.go | 147 +++++++++++++++++++++++++ 9 files changed, 400 insertions(+), 31 deletions(-) create mode 100644 internal/database/elastic/connect.go create mode 100644 internal/database/elastic/functions.go create mode 100644 testMain.go diff --git a/README.md b/README.md index e2dc7e5..f774907 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ O Log Guardian Ć© uma biblioteca desenvolvida para padronizar e gerenciar logs d šŸ”¹ ConfiguraĆ§Ć£o FlexĆ­vel: Permite a fĆ”cil integraĆ§Ć£o com diferentes sistemas, possibilitando a customizaĆ§Ć£o e configuraĆ§Ć£o dos logs de acordo com as necessidades especĆ­ficas. -šŸ”¹ ConexĆ£o com Banco de Dados: AlĆ©m da gestĆ£o dos logs, o Log Guardian pode se integrar a diferentes tipos de banco de dados, como PostgreSQL, MySQL, SQLite e MongoDB. A configuraĆ§Ć£o Ć© simples, utilizando variĆ”veis de ambiente para especificar os detalhes de conexĆ£o. +šŸ”¹ ConexĆ£o com Banco de Dados: AlĆ©m da gestĆ£o dos logs, o Log Guardian pode se integrar a diferentes tipos de banco de dados, como PostgreSQL, MySQL, SQLite, ElasticSearch e MongoDB. A configuraĆ§Ć£o Ć© simples, utilizando variĆ”veis de ambiente para especificar os detalhes de conexĆ£o. šŸ”¹ InserĆ§Ć£o AutomĆ”tica de Logs: Quando configurado corretamente com variĆ”veis de ambiente, o Log Guardian Ć© capaz de inserir automaticamente os logs no banco de dados especificado. @@ -40,37 +40,49 @@ O Log Guardian utiliza variĆ”veis de ambiente para configurar suas operaƧƵes d

Banco de Dados Relacional

#### PostgreSQL -``` + +```textplein POSTGRES_HOST: Define o endereƧo do host para o PostgreSQL. POSTGRES_EXTERNAL_PORT: Especifica a porta externa para o PostgreSQL. POSTGRES_USER: Nome de usuĆ”rio para autenticaĆ§Ć£o no PostgreSQL. POSTGRES_PASSWORD: Senha para autenticaĆ§Ć£o no PostgreSQL. POSTGRES_DB: Nome do banco de dados PostgreSQL a ser utilizado. ``` + #### MySQL -``` + +```textplein MYSQL_HOST: Define o endereƧo do host para o MySQL. MYSQL_PORT: Especifica a porta para o MySQL. MYSQL_USER: Nome de usuĆ”rio para autenticaĆ§Ć£o no MySQL. MYSQL_PASSWORD: Senha para autenticaĆ§Ć£o no MySQL. MYSQL_DBNAME: Nome do banco de dados MySQL a ser utilizado. ``` + #### SQLite -``` + +```textplein SQLITE_PATH: Caminho do arquivo SQLite, se for o banco de dados escolhido. ```

Banco de Dados NoSQL

#### MongoDB -``` +```textplein MONGODB_URI: Define o URI de conexĆ£o para o MongoDB. MONGODB_DBNAME: Nome do banco de dados MongoDB a ser utilizado. ``` -

ConfiguraĆ§Ć£o Geral

+#### ElasticSearch +```textplein +ELASTIC_URI: Define o URI de conexĆ£o para o ElasticSearch. +DATABASE_TYPE: Deve ser configurado como "elastic" para utilizar o ElasticSearch como destino dos logs. ``` + +

ConfiguraĆ§Ć£o Geral

+ +```textplein DATABASE_TYPE: Especifica o tipo de banco de dados a ser utilizado pelo Log Guardian (Valores: sqlite, postgres, mysql, mongodb). ``` @@ -79,3 +91,5 @@ DATABASE_TYPE: Especifica o tipo de banco de dados a ser utilizado pelo Log Guar Para utilizar as funƧƵes automĆ”ticas do go-log-guardian, Ć© obrigatĆ³rio o uso da variĆ”vel DATABASE_TYPE, pois algumas validaƧƵes sĆ£o executadas com base nesta variĆ”vel antes de chamar as rotinas de inserĆ§Ć£o. Certifique-se de fornecer valores vĆ”lidos e corretos para cada uma dessas variĆ”veis de ambiente. Isso garante uma conexĆ£o adequada e o funcionamento correto do Log Guardian com o banco de dados desejado. + +āš ļø O arquivo testMain.go foi criado para testar funcionalidades de gerenciamento de logs. Para executar esta aplicaĆ§Ć£o, Ć© necessĆ”rio configurar o ambiente utilizando o Docker Compose que pode ser encontrado no repo [docker-build-library](https://github.com/fonteeboa/docker-build-library/tree/master/golang/go-log-guardian) diff --git a/README_en_us.md b/README_en_us.md index 2d2137d..c31da35 100644 --- a/README_en_us.md +++ b/README_en_us.md @@ -18,7 +18,7 @@ Log Guardian is a library developed to standardize and efficiently manage logs i šŸ”¹ Flexible Configuration: Allows easy integration with different systems, enabling customization and configuration of logs according to specific needs. -šŸ”¹ Database Connection: In addition to log management, Log Guardian can integrate with different types of databases such as PostgreSQL, MySQL, SQLite, and MongoDB. Configuration is simple, using environment variables to specify connection details. +šŸ”¹ Database Connection: In addition to log management, Log Guardian can integrate with different types of databases such as PostgreSQL, MySQL, SQLite, ElasticSearch and MongoDB. Configuration is simple, using environment variables to specify connection details. šŸ”¹ Automatic Log Insertion: When correctly configured with environment variables, Log Guardian can automatically insert logs into the specified database. @@ -39,37 +39,50 @@ Log Guardian uses environment variables to configure its database operations, in

Relational Database

#### PostgreSQL -``` + +```textplein POSTGRES_HOST: Defines the host address for PostgreSQL. POSTGRES_EXTERNAL_PORT: Specifies the external port for PostgreSQL. POSTGRES_USER: Username for authentication in PostgreSQL. POSTGRES_PASSWORD: Password for authentication in PostgreSQL. POSTGRES_DB: Name of the PostgreSQL database to be used. ``` + #### MySQL -``` + +```textplein MYSQL_HOST: Defines the host address for MySQL. MYSQL_PORT: Specifies the port for MySQL. MYSQL_USER: Username for authentication in MySQL. MYSQL_PASSWORD: Password for authentication in MySQL. MYSQL_DBNAME: Name of the MySQL database to be used. ``` + #### SQLite -``` + +```textplein SQLITE_PATH: Path to the SQLite file if it is the chosen database. ```

NoSQL Database

#### MongoDB -``` + +```textplein MONGODB_URI: Defines the connection URI for MongoDB. MONGODB_DBNAME: Name of the MongoDB database to be used. ``` -

General Configuration

+#### ElasticSearch +```textpleintextplein +ELASTIC_URI: Specifies the connection URI for ElasticSearch. +DATABASE_TYPE: Must be set to "elastic" to use ElasticSearch as the log destination. ``` + +

General Configuration

+ +```textplein DATABASE_TYPE: Specifies the type of database to be used by Log Guardian (Values: sqlite, postgres, mysql, mongodb). ``` @@ -78,3 +91,5 @@ DATABASE_TYPE: Specifies the type of database to be used by Log Guardian (Values To utilize the automatic functions of go-log-guardian, using the DATABASE_TYPE variable is mandatory, as some validations are performed based on this variable before calling the insertion routines. Ensure to provide valid and correct values for each of these environment variables. This ensures proper connection and functioning of Log Guardian with the desired database. + +āš ļø The testMain.go file was created to test log management functionality. To execute this application, you need to configure the environment using Docker Compose, which can be found in the [docker-build-library]((https://github.com/fonteeboa/docker-build-library/tree/master/golang/go-log-guardian)) repository. diff --git a/go.mod b/go.mod index 9c9c3b5..867d845 100644 --- a/go.mod +++ b/go.mod @@ -1,11 +1,17 @@ module github.com/fonteeBoa/go-log-guardian -go 1.21 +go 1.22 + +toolchain go1.22.3 replace github.com/fonteeBoa/go-log-guardian => github.com/fonteeBoa/go-log-guardian v1.0.3 require ( github.com/davecgh/go-spew v1.1.1 // indirect + github.com/elastic/elastic-transport-go/v8 v8.6.0 // indirect + github.com/elastic/go-elasticsearch/v8 v8.16.0 // indirect + github.com/go-logr/logr v1.4.2 // indirect + github.com/go-logr/stdr v1.2.2 // indirect github.com/go-sql-driver/mysql v1.7.0 // indirect github.com/golang/snappy v0.0.1 // indirect github.com/jackc/pgpassfile v1.0.0 // indirect @@ -17,12 +23,15 @@ require ( github.com/mattn/go-sqlite3 v1.14.17 // indirect github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/stretchr/testify v1.8.4 // indirect + github.com/stretchr/testify v1.9.0 // indirect github.com/xdg-go/pbkdf2 v1.0.0 // indirect github.com/xdg-go/scram v1.1.2 // indirect github.com/xdg-go/stringprep v1.0.4 // indirect github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d // indirect go.mongodb.org/mongo-driver v1.13.0 // indirect + go.opentelemetry.io/otel v1.28.0 // indirect + go.opentelemetry.io/otel/metric v1.28.0 // indirect + go.opentelemetry.io/otel/trace v1.28.0 // indirect golang.org/x/crypto v0.14.0 // indirect golang.org/x/sync v0.1.0 // indirect golang.org/x/text v0.13.0 // indirect diff --git a/go.sum b/go.sum index d876ea1..af66e0b 100644 --- a/go.sum +++ b/go.sum @@ -1,6 +1,15 @@ 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/elastic/elastic-transport-go/v8 v8.6.0 h1:Y2S/FBjx1LlCv5m6pWAF2kDJAHoSjSRSJCApolgfthA= +github.com/elastic/elastic-transport-go/v8 v8.6.0/go.mod h1:YLHer5cj0csTzNFXoNQ8qhtGY1GTvSqPnKWKaqQE3Hk= +github.com/elastic/go-elasticsearch/v8 v8.16.0 h1:f7bR+iBz8GTAVhwyFO3hm4ixsz2eMaEy0QroYnXV3jE= +github.com/elastic/go-elasticsearch/v8 v8.16.0/go.mod h1:lGMlgKIbYoRvay3xWBeKahAiJOgmFDsjZC39nmO3H64= +github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= +github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-sql-driver/mysql v1.7.0 h1:ueSltNNllEqE3qcWBTD0iQd3IpL/6U+mJxLkazJ7YPc= github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI= github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4= @@ -29,6 +38,7 @@ github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UV github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= 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.1.2 h1:FHX5I5B4i4hKRVRBCFRxq1iQRej7WO3hhBuJf+UUySY= @@ -40,6 +50,12 @@ github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7Jul github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= go.mongodb.org/mongo-driver v1.13.0 h1:67DgFFjYOCMWdtTEmKFpV3ffWlFnh+CYZ8ZS/tXWUfY= go.mongodb.org/mongo-driver v1.13.0/go.mod h1:/rGBTebI3XYboVmgz+Wv3Bcbl3aD0QF9zl6kDDw18rQ= +go.opentelemetry.io/otel v1.28.0 h1:/SqNcYk+idO0CxKEUOtKQClMK/MimZihKYMruSMViUo= +go.opentelemetry.io/otel v1.28.0/go.mod h1:q68ijF8Fc8CnMHKyzqL6akLO46ePnjkgfIMIjUIX9z4= +go.opentelemetry.io/otel/metric v1.28.0 h1:f0HGvSl1KRAU1DLgLGFjrwVyismPlnuU6JD6bOeuA5Q= +go.opentelemetry.io/otel/metric v1.28.0/go.mod h1:Fb1eVBFZmLVTMb6PPohq3TO9IIhUisDsbJoL/+uQW4s= +go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g= +go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= diff --git a/internal/database/dbhandler/handler.go b/internal/database/dbhandler/handler.go index cda5917..302c059 100644 --- a/internal/database/dbhandler/handler.go +++ b/internal/database/dbhandler/handler.go @@ -5,9 +5,11 @@ import ( "fmt" "os" + "github.com/elastic/go-elasticsearch/v8" "go.mongodb.org/mongo-driver/mongo" "gorm.io/gorm" + "github.com/fonteeBoa/go-log-guardian/internal/database/elastic" "github.com/fonteeBoa/go-log-guardian/internal/database/mongodb" "github.com/fonteeBoa/go-log-guardian/internal/database/mysql" "github.com/fonteeBoa/go-log-guardian/internal/database/postgres" @@ -16,42 +18,48 @@ import ( // GetConnection retrieves the database connection based on the DATABASE_TYPE environment variable. // -// It returns the *gorm.DB and *mongo.Client connections and an error. -func GetConnection() (*gorm.DB, *mongo.Client, error) { +// It returns the *gorm.DB, *mongo.Client, *elasticsearch.Client connections, and an error. +func GetConnection() (*gorm.DB, *mongo.Client, *elasticsearch.Client, error) { dbType := os.Getenv("DATABASE_TYPE") if dbType == "" { fmt.Println("DATABASE_TYPE not set") - return nil, nil, errors.New("database type not specified") + return nil, nil, nil, errors.New("database type not specified") } var gormDB *gorm.DB var mongoClient *mongo.Client + var elasticClient *elasticsearch.Client var err error switch dbType { case "postgres": gormDB, err = postgres.Connect() if err != nil { - return nil, nil, err + return nil, nil, nil, err } case "mysql": gormDB, err = mysql.Connect() if err != nil { - return nil, nil, err + return nil, nil, nil, err } case "sqlite": gormDB, err = sqlite.Connect() if err != nil { - return nil, nil, err + return nil, nil, nil, err } case "mongodb": mongoClient, err = mongodb.Connect() if err != nil { - return nil, nil, err + return nil, nil, nil, err + } + case "elastic": + elasticClient, err = elastic.Connect() + if err != nil { + return nil, nil, nil, err } default: - return nil, nil, errors.New("unsupported database type") + return nil, nil, nil, errors.New("unsupported database type") } - return gormDB, mongoClient, nil + return gormDB, mongoClient, elasticClient, nil } diff --git a/internal/database/elastic/connect.go b/internal/database/elastic/connect.go new file mode 100644 index 0000000..8e9be11 --- /dev/null +++ b/internal/database/elastic/connect.go @@ -0,0 +1,38 @@ +package elastic + +import ( + "log" + "os" + + "github.com/elastic/go-elasticsearch/v8" +) + +// Connect establishes a connection to the ElasticSearch cluster. +// +// It reads the ElasticSearch URI from the environment variable `ELASTIC_URI`. +// +// Returns: +// - A pointer to an elasticsearch.Client instance. +// - An error, if the connection fails. +func Connect() (*elasticsearch.Client, error) { + cfg := elasticsearch.Config{ + Addresses: []string{ + os.Getenv("ELASTIC_URI"), + }, + } + + client, err := elasticsearch.NewClient(cfg) + if err != nil { + return nil, err + } + + // Test connection + res, err := client.Info() + if err != nil { + return nil, err + } + defer res.Body.Close() + + log.Println("ElasticSearch connection established") + return client, nil +} diff --git a/internal/database/elastic/functions.go b/internal/database/elastic/functions.go new file mode 100644 index 0000000..bad8ebd --- /dev/null +++ b/internal/database/elastic/functions.go @@ -0,0 +1,91 @@ +package elastic + +import ( + "encoding/json" + "os" + + "github.com/elastic/go-elasticsearch/v8" + "github.com/elastic/go-elasticsearch/v8/esutil" +) + +// getIndexName retorna o nome do Ć­ndice baseado na variĆ”vel de ambiente ELASTIC_INDEX. +// Se a variĆ”vel nĆ£o estiver definida, retorna o valor padrĆ£o "log-guardian-audit". +func getIndexName() string { + indexName := os.Getenv("ELASTIC_INDEX") + if indexName == "" { + return "log-guardian-audit" + } + return indexName +} + +// InsertBaseLog inserts a base log into the specified index in ElasticSearch. +// +// Parameters: +// - client: A pointer to an elasticsearch.Client instance. +// - log: The base log to be inserted. +// +// Returns: +// - An error if the operation fails. +func InsertBaseLog(client *elasticsearch.Client, log interface{}) error { + return insertLog(client, getIndexName(), log) +} + +// InsertFunctionLog inserts a function log into the specified index in ElasticSearch. +// +// Parameters: +// - client: A pointer to an elasticsearch.Client instance. +// - log: The function log to be inserted. +// +// Returns: +// - An error if the operation fails. +func InsertFunctionLog(client *elasticsearch.Client, log interface{}) error { + return insertLog(client, getIndexName(), log) +} + +// InsertDatabaseLog inserts a database log into the specified index in ElasticSearch. +// +// Parameters: +// - client: A pointer to an elasticsearch.Client instance. +// - log: The database log to be inserted. +// +// Returns: +// - An error if the operation fails. +func InsertDatabaseLog(client *elasticsearch.Client, log interface{}) error { + return insertLog(client, getIndexName(), log) +} + +// InsertRequestLog inserts a request log into the specified index in ElasticSearch. +// +// Parameters: +// - client: A pointer to an elasticsearch.Client instance. +// - log: The request log to be inserted. +// +// Returns: +// - An error if the operation fails. +func InsertRequestLog(client *elasticsearch.Client, log interface{}) error { + return insertLog(client, getIndexName(), log) +} + +// insertLog is a generic function to insert a log into a specified index. +// +// Parameters: +// - client: A pointer to an elasticsearch.Client instance. +// - index: The index name where the log will be inserted. +// - log: The log data to be inserted. +// +// Returns: +// - An error if the operation fails. +func insertLog(client *elasticsearch.Client, index string, log interface{}) error { + data, err := json.Marshal(log) + if err != nil { + return err + } + + res, err := client.Index(index, esutil.NewJSONReader(data)) + if err != nil { + return err + } + defer res.Body.Close() + + return nil +} diff --git a/internal/services/savelogs.go b/internal/services/savelogs.go index cfe2d10..62aa69d 100644 --- a/internal/services/savelogs.go +++ b/internal/services/savelogs.go @@ -3,12 +3,11 @@ package services import ( "errors" - pkg "github.com/fonteeBoa/go-log-guardian/pkg/domain" - + "github.com/elastic/go-elasticsearch/v8" "github.com/fonteeBoa/go-log-guardian/internal/database/dbhandler" - + "github.com/fonteeBoa/go-log-guardian/internal/database/elastic" "github.com/fonteeBoa/go-log-guardian/internal/database/mongodb" - + pkg "github.com/fonteeBoa/go-log-guardian/pkg/domain" "go.mongodb.org/mongo-driver/mongo" "gorm.io/gorm" ) @@ -18,13 +17,13 @@ import ( // It takes a log interface{} as a parameter. // Returns an error if there was a problem saving the log. func SaveLog(log interface{}) error { - gormDB, mongoClient, err := dbhandler.GetConnection() + gormDB, mongoClient, elasticClient, err := dbhandler.GetConnection() if err != nil { return err } - if gormDB == nil && mongoClient == nil { + if gormDB == nil && mongoClient == nil && elasticClient == nil { return errors.New("no valid database connection provided") } @@ -42,8 +41,14 @@ func SaveLog(log interface{}) error { } } - return nil + if elasticClient != nil { + errElastic := insertLogElastic(elasticClient, log) + if errElastic != nil { + return errElastic + } + } + return nil } // insertLogGorm inserts a log entry into the database using the provided *gorm.DB connection. @@ -76,7 +81,7 @@ func insertLogGorm(db *gorm.DB, log interface{}) error { // - pkg.LogFunction // - pkg.LogDatabase // - pkg.LogRequest -// +// Returns: // Returns an error if the insertion fails. func insertLogMongo(db *mongo.Client, log interface{}) error { switch log := log.(type) { @@ -92,3 +97,29 @@ func insertLogMongo(db *mongo.Client, log interface{}) error { return nil } } + +// insertLogElastic inserts a log into an ElasticSearch index. +// +// Parameters: +// - client: ElasticSearch client instance. +// log is the log to be inserted. It can be one of the following types: +// - pkg.LogDetails +// - pkg.LogFunction +// - pkg.LogDatabase +// - pkg.LogRequest +// Returns: +// - An error if the operation fails. +func insertLogElastic(client *elasticsearch.Client, log interface{}) error { + switch log := log.(type) { + case pkg.LogDetails: + return elastic.InsertBaseLog(client, log) + case pkg.LogFunction: + return elastic.InsertFunctionLog(client, log) + case pkg.LogDatabase: + return elastic.InsertDatabaseLog(client, log) + case pkg.LogRequest: + return elastic.InsertRequestLog(client, log) + default: + return nil + } +} diff --git a/testMain.go b/testMain.go new file mode 100644 index 0000000..b156cea --- /dev/null +++ b/testMain.go @@ -0,0 +1,147 @@ +package main + +import ( + "fmt" + "log" + "os" + + "github.com/fonteeBoa/go-log-guardian/pkg" + "github.com/fonteeBoa/go-log-guardian/pkg/domain" +) + +func main() { + dbConfigs := map[string]map[string]string{ + "postgres": { + "POSTGRES_HOST": "127.0.0.1", // Safe: Localhost address for testing + "POSTGRES_EXTERNAL_PORT": "5432", // Safe: Standard PostgreSQL port + "POSTGRES_USER": "admin", // Safe: Test user for local database + "POSTGRES_PASSWORD": "admin", // Safe: Test password for local database + "POSTGRES_DB": "logguardian", // Safe: Test database name + }, + "mysql": { + "MYSQL_HOST": "127.0.0.1", // Safe: Localhost address for testing + "MYSQL_PORT": "3306", // Safe: Standard MySQL port + "MYSQL_USER": "admin", // Safe: Test user for local database + "MYSQL_PASSWORD": "admin", // Safe: Test password for local database + "MYSQL_DBNAME": "logguardian", // Safe: Test database name + }, + "sqlite": { + "SQLITE_PATH": "./data/logguardian.db", // Safe: Local SQLite file for testing + }, + "mongodb": { + "MONGODB_URI": "mongodb://127.0.0.1:27017", // Safe: Local MongoDB URI for testing + "MONGODB_DBNAME": "logguardian", // Safe: Test database name + }, + "elastic": { + "ELASTIC_URI": "http://127.0.0.1:9200", // Safe: Local ElasticSearch URI for testing + }, + } + + for dbType, config := range dbConfigs { + fmt.Printf("\n=== Testing with database type: %s ===\n", dbType) + + setEnvVariables(config) + + if err := os.Setenv("DATABASE_TYPE", dbType); err != nil { + log.Fatalf("Failed to set DATABASE_TYPE: %v", err) + } + + runTestsForDatabase() + } +} + +func setEnvVariables(config map[string]string) { + for key, value := range config { + if err := os.Setenv(key, value); err != nil { + log.Fatalf("Failed to set environment variable %s: %v", key, err) + } + } +} + +func runTestsForDatabase() { + fmt.Println("== Testing LogFunction ==") + success, logFunction := pkg.LogFunction( + domain.LOG_INFO, + "TestFunction", + "Generic function error", + "Specific function error", + ) + printResult(success, logFunction) + + fmt.Println("\n== Testing LogDataBase ==") + success, logDatabase := pkg.LogDataBase( + domain.LOG_ERR, + "TestTable", + "SELECT * FROM TestTable", + "Generic database error", + "Specific database error", + ) + printResult(success, logDatabase) + + fmt.Println("\n== Testing LogRequests ==") + success, logRequest := pkg.LogRequests( + domain.LOG_WARNING, + "GET", + 200, + "/test-endpoint", + 1024, + "Generic request error", + "Specific request error", + ) + printResult(success, logRequest) + + fmt.Println("\n== Testing Log ==") + success, logDetails := pkg.Log( + domain.LOG_ALERT, + "Generic log error", + "Specific log error", + ) + printResult(success, logDetails) + + testSpecificLogFunctions() +} + +func testSpecificLogFunctions() { + logTests := []struct { + name string + logFunc func(string, string) (bool, domain.LogDetails) + genericErr string + errMsg string + }{ + {"LogEmerg", adaptLogFunction(pkg.LogEmerg), "Generic emerg error", "Specific emerg error"}, + {"LogCritical", adaptLogFunction(pkg.LogCritical), "Generic critical error", "Specific critical error"}, + {"LogAlert", adaptLogFunction(pkg.LogAlert), "Generic alert", "Specific alert"}, + {"LogWarning", adaptLogFunction(pkg.LogWarning), "Generic warning", "Specific warning"}, + {"LogNotice", adaptLogFunction(pkg.LogNotice), "Generic notice", "Specific notice"}, + {"LogInfo", adaptLogFunction(pkg.LogInfo), "Generic info", "Specific info"}, + {"LogError", func(genericErr, specificErr string) (bool, domain.LogDetails) { + return pkg.LogError(domain.LOG_ERR, genericErr, specificErr) + }, "Generic error", "Specific error"}, + } + + for _, test := range logTests { + fmt.Printf("\n--- Testing %s ---\n", test.name) + success, logDetails := test.logFunc(test.genericErr, test.errMsg) + printResult(success, logDetails) + } + + fmt.Println("\n--- Testing LogDebug ---") + success := pkg.LogDebug("Generic debug error", "Specific debug error") + fmt.Printf("LogDebug Success: %v\n", success) +} + +func adaptLogFunction(f func(string, string) (bool, domain.LogDetails)) func(string, string) (bool, domain.LogDetails) { + return func(genericErrMsg, errMsg string) (bool, domain.LogDetails) { + return f(genericErrMsg, errMsg) + } +} + +func printResult(success bool, logData interface{}) { + if !success { + log.Println("Log operation failed!") + return + } + + fmt.Println("Log operation successful!") + fmt.Printf("Log Data: %+v\n", logData) +}