Skip to content

Commit 7155052

Browse files
authored
Merge pull request #1 from PSNAppz/develop
Release v1.0
2 parents a0bbb1b + 686cdad commit 7155052

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

55 files changed

+1692
-26
lines changed

.env.sample

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1-
POSTGRES_USER=postgres
2-
POSTGRES_PASSWORD=123456
3-
POSTGRES_HOST=localhost
1+
POSTGRES_USER=fold-elk
2+
POSTGRES_PASSWORD=password
3+
POSTGRES_HOST=postgres
44
POSTGRES_PORT=5432
5-
POSTGRES_DB=fold-etl-pipeline
5+
POSTGRES_DB=fold_elk
66

7-
ELASTICSEARCH_URL="http://elasticsearch:9200"
7+
ELASTICSEARCH_URL="http://elasticsearch:9200"
8+
ELASTIC_VERSION=7.17.9

.gitignore

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,39 @@
1414
# Dependency directories (remove the comment below to include it)
1515
# vendor/
1616
.env
17+
18+
19+
# Local .terraform directories
20+
**/.terraform/*
21+
22+
# .tfstate files
23+
*.tfstate
24+
*.tfstate.*
25+
26+
# Crash log files
27+
crash.log
28+
crash.*.log
29+
30+
# Exclude all .tfvars files, which are likely to contain sensitive data, such as
31+
# password, private keys, and other secrets. These should not be part of version
32+
# control as they are data points which are potentially sensitive and subject
33+
# to change depending on the environment.
34+
*.tfvars
35+
*.tfvars.json
36+
37+
# Ignore override files as they are usually used to override resources locally and so
38+
# are not checked in
39+
override.tf
40+
override.tf.json
41+
*_override.tf
42+
*_override.tf.json
43+
44+
# Include override files you do wish to add to version control using negated pattern
45+
# !example_override.tf
46+
47+
# Include tfplan files to ignore the plan output of command: terraform plan -out=tfplan
48+
# example: *tfplan*
49+
50+
# Ignore CLI configuration files
51+
.terraformrc
52+
terraform.rc

.terraform.lock.hcl

Lines changed: 43 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Dockerfile

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
FROM golang:1.19.5
2+
3+
COPY go.mod go.sum /go/src/github.com/PSNAppz/Fold-ELK/
4+
WORKDIR /go/src/github.com/PSNAppz/Fold-ELK
5+
RUN go mod download
6+
7+
COPY . /go/src/github.com/PSNAppz/Fold-ELK
8+
RUN go build -o /usr/bin/fold-elk github.com/PSNAppz/Fold-ELK/cmd/api
9+
10+
EXPOSE 8080 8080
11+
ENTRYPOINT ["/usr/bin/fold-elk"]
12+

README.md

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,41 @@
11
# Fold-ELK
22

3+
[![Run in Postman](https://run.pstmn.io/button.svg)](https://app.getpostman.com/run-collection/12298080-b2a522f0-5323-4aa1-b803-c73160cde976?action=collection%2Ffork&collection-url=entityId%3D12298080-b2a522f0-5323-4aa1-b803-c73160cde976%26entityType%3Dcollection%26workspaceId%3D42654ab9-e148-4e67-b4b3-90fd805dfb7f)
4+
5+
The postman collection contains all the API endpoints along with examples.
6+
### The objectives of this repo are as follows:
7+
8+
- To build a data pipeline that syncs and transforms the data stored in a PostgresSQL Database to Elasticsearch, making the data searchable in a fuzzy and relational manner.
9+
- To build a REST API service that will query Elasticsearch.
10+
11+
### Project brief
12+
13+
Fold-ELK has a set of configuration files for the ELK stack (Elasticsearch, Logstash, Kibana). You can follow the below steps to get the ELK stack up and running.
14+
CRUD APIs are built using go-gin and the data is stored in PostgresSQL. The data is then synced to Elasticsearch using Logstash. The APIs are then used to query Elasticsearch.
15+
Data is seeded using faker, which is used to populate the PostgresSQL database.
16+
17+
## Getting Started
18+
19+
### Prerequisites
20+
21+
- Docker
22+
- Docker Compose
23+
- Go
24+
25+
### Setting up the docker environment
26+
27+
- Clone the repo
28+
- Run `mv .env.example .env` to create the environment file
29+
- Run `docker-compose up --build` to build and bootup the ELK stack
30+
- Once the ELK stack is up and running, you can use the below
31+
- Kibana: http://localhost:5601
32+
- Elasticsearch: http://localhost:9200
33+
- API: http://localhost:8080
34+
35+
### Running the API locally
36+
37+
The CRUD API can be run locally using the below steps:
38+
39+
- Make sure the ELK stack is up and running using the above steps
40+
- Run `go build -o bin/application cmd/api/main.go` to build the API binary
41+
- Run `./bin/application` to run the API and start listening on port 8080

bin/application

15.8 MB
Binary file not shown.

cmd/api/main.go

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
package main
2+
3+
import (
4+
"os"
5+
"strconv"
6+
7+
"github.com/elastic/go-elasticsearch/v8"
8+
9+
"github.com/PSNAppz/Fold-ELK/db"
10+
"github.com/PSNAppz/Fold-ELK/handler"
11+
"github.com/gin-gonic/gin"
12+
"github.com/rs/zerolog"
13+
)
14+
15+
func main() {
16+
var dbPort int
17+
var err error
18+
logger := zerolog.New(os.Stderr).With().Timestamp().Logger()
19+
20+
port := os.Getenv("POSTGRES_PORT")
21+
if dbPort, err = strconv.Atoi(port); err != nil {
22+
logger.Err(err).Msg("failed to parse database port")
23+
os.Exit(1)
24+
}
25+
dbConfig := db.Config{
26+
Host: os.Getenv("POSTGRES_HOST"),
27+
Port: dbPort,
28+
Username: os.Getenv("POSTGRES_USER"),
29+
Password: os.Getenv("POSTGRES_PASSWORD"),
30+
DbName: os.Getenv("POSTGRES_DB"),
31+
Logger: logger,
32+
}
33+
logger.Info().Interface("config", &dbConfig).Msg("config:")
34+
dbInstance, err := db.Init(dbConfig)
35+
if err != nil {
36+
logger.Err(err).Msg("Connection failed")
37+
os.Exit(1)
38+
}
39+
logger.Info().Msg("Database connection established")
40+
41+
esClient, err := elasticsearch.NewDefaultClient()
42+
if err != nil {
43+
logger.Err(err).Msg("Connection failed")
44+
os.Exit(1)
45+
}
46+
47+
h := handler.New(dbInstance, esClient, logger)
48+
router := gin.Default()
49+
rg := router.Group("/v1")
50+
h.Register(rg)
51+
router.Run(":8080")
52+
}

db/database.go

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package db
2+
3+
import (
4+
"database/sql"
5+
"fmt"
6+
7+
_ "github.com/lib/pq"
8+
"github.com/rs/zerolog"
9+
)
10+
11+
var (
12+
ErrNoRecord = fmt.Errorf("no matching record found")
13+
insertOp = "insert"
14+
deleteOp = "delete"
15+
updateOp = "update"
16+
)
17+
18+
type Database struct {
19+
Conn *sql.DB
20+
Logger zerolog.Logger
21+
}
22+
23+
type Config struct {
24+
Host string
25+
Port int
26+
Username string
27+
Password string
28+
DbName string
29+
Logger zerolog.Logger
30+
}
31+
32+
func Init(cfg Config) (Database, error) {
33+
db := Database{}
34+
dsn := fmt.Sprintf("host=%s port=%d user=%s password=%s dbname=%s sslmode=disable",
35+
cfg.Host, cfg.Port, cfg.Username, cfg.Password, cfg.DbName)
36+
conn, err := sql.Open("postgres", dsn)
37+
if err != nil {
38+
return db, err
39+
}
40+
41+
db.Conn = conn
42+
db.Logger = cfg.Logger
43+
err = db.Conn.Ping()
44+
if err != nil {
45+
return db, err
46+
}
47+
return db, nil
48+
}

0 commit comments

Comments
 (0)