Skip to content

Commit

Permalink
closes #73; added comments, added option to enable features
Browse files Browse the repository at this point in the history
  • Loading branch information
sooraj-sky committed Feb 26, 2023
1 parent 232a058 commit 19d966a
Show file tree
Hide file tree
Showing 15 changed files with 225 additions and 182 deletions.
61 changes: 34 additions & 27 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,23 +25,29 @@ See Docker Hub Image
https://hub.docker.com/r/soorajsky/sky-meter

## Environment variables
Currenly we have two environment variables.
1. sentry_dsn
2. PORT
| Variable | Type | Example |
|----------------|---------|-----------------|
| DnsServer | string | 8.8.8.8 |
| Port | string | 8000 |
| EmailPass | string | youremailpass |
| EmailFrom | string | from@gmail.com |
| EmailPort | string | 583 |
| EmailServer | string | smtp.gmail.com |
| OpsgenieSecret | string | examplesecret |
| SentryDsn | string | exapledsnvalue |
| Mode | string | prod |
| DbUrl | string | host=localhost user=postgres password=postgres dbname=postgres port=5433 sslmode=disable |



- You can create sentry project and imput the **sentry_dsn** as env variable.
- You can export the **PORT** variable to set the http port of the server

## Add URLs to check
To add a URL to minitoring is pertty simple. Create **settings.yml** to add your endpoints to monitor. See an example of **settings.yml** below
```sh
opegenie:
- enabled: false
enabled: false
email:
- enabled: true
server: smtp.gmail.com
port: 587
sender: testemail@gmail.com
enabled: true
groups:
- name: prod
emails:
Expand Down Expand Up @@ -89,28 +95,29 @@ Clone the code
$ git clone https://github.com/sooraj-sky/sky-meter.git
$ cd sky-meter
```
Run the postgres docker container
Run the postgres docker container (skip this step if you already have a database)
```sh
$ docker-compose up -d
```
Added Env Option: You can enable sentry by adding
Export ENV variables (Sentry will work only in dev mode)
If Email is disbled on **settings.yml** the following variables are not needed.
1. EmailPass
2. EmailFrom
3. EmailPort
4. EmailServer

**SentryDsn** is only needed when **Mode=dev**

Export sentry dsn
```sh
$ export mode="dev"
$ export sentry_dsn="<yourDsnHere>"
```
Export the port
```sh
$ export PORT=8080
```
Export opsgenieSecret
```sh
$ export opsgeniesecret="your-opsgenie-api-keyhere"
```
Export email passsword
```sh
export emailpass="your-email-pass-here"
$ export DnsServer="8.8.8.8" #requied
$ export DbUrl="host=localhost user=postgres password=postgres dbname=postgres port=5433 sslmode=disable" #requied
$ export EmailPass="your-pass-here" #requied when Email is Enabled
$ export EmailFrom="youremail@server.com" #requied when Email is Enabled
$ export EmailPort="587" #requied when Email is Enabled
$ export EmailServer="smtp.server-address-here.com" #requied when Email is Enabled
$ export OpsgenieSecret="your-opsgenie-key-here" #requied when Opsgenie is Enabled on settings.yml
$ export Mode="dev"
$ export SentryDsn="your-DSn-key-here" #requied when Mode="dev"
```
Run the project
```sh
Expand Down
18 changes: 13 additions & 5 deletions cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,23 @@ import (
"log"
dbops "sky-meter/packages/dbops"
skyenv "sky-meter/packages/env"
skymeter "sky-meter/packages/httpserver"
sentry "sky-meter/packages/logger"
yamlops "sky-meter/packages/yamlops"
)

func init() {

// Initialize the environment variables
skyenv.InitEnv()
}

func main() {
log.Println("Launching sky-meter")

// Initialize the Sentry logger
sentry.SentryInit()

// Get all the environment variables
allEnv := skyenv.GetEnv()
dbconnect := allEnv.DbUrl
db, err := gorm.Open(postgres.New(postgres.Config{
Expand All @@ -28,16 +33,19 @@ func main() {
}), &gorm.Config{})

if err != nil {
log.Println(err)

// Exit the program if there is an error connecting to the database
log.Fatal(err)
}

// Read the YAML file to get the list of endpoints to monitor
endpoints := yamlops.InputYml()
dbops.InitialMigration(db)
dbops.InsertUrlsToDb(db, endpoints)
dbops.RemoveOldEntry(db, endpoints)
log.Println("Updated sky-meter targets")
log.Println("Staring sky-meter Health Check")
gocron.Every(1).Second().Do(dbops.GetUrlFrequency, db)
<-gocron.Start()
skymeter.InitServer()
gocron.Every(1).Second().Do(dbops.GetUrlFrequency, db, endpoints)
<-gocron.Start() // Start the scheduler and block the main thread until it exits

}
46 changes: 0 additions & 46 deletions input.json

This file was deleted.

8 changes: 2 additions & 6 deletions models/models.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,14 +97,11 @@ type SmtpErr struct {
}

type UserInput struct {
Opegenie []struct {
Opegenie struct {
Enabled bool
}
Email []struct {
Email struct {
Enabled bool
Server string
Port int
Sender string
}

Groups []struct {
Expand All @@ -130,7 +127,6 @@ type AlertGroups struct {

type AllEnvs struct {
DnsServer string
Port string
EmailPass string
EmailFrom string
EmailPort string
Expand Down
33 changes: 32 additions & 1 deletion packages/alerts/alert.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,24 +16,30 @@ import (
"strconv"
)

// SendMail function sends an email to the specified recipient(s) with the given email content

func SendMail(i models.SmtpErr) {

// Get the environment variables for the email server details and the password for the email account.
allEnv := skyenv.GetEnv()
emailPass := allEnv.EmailPass

// Create a new template from the error.html file and handle any errors that occur during the parsing of the template.
t := template.New("error.html")

var err error
t, err = t.ParseFiles("templates/error.html")
if err != nil {
log.Println(err)
}

// Execute the template with the SmtpErr instance to get the final HTML email body.
var tpl bytes.Buffer
if err := t.Execute(&tpl, i); err != nil {
log.Println(err)
}

// Loop through each recipient email address listed in the SmtpErr instance, create a new email message, set the necessary headers,
// and send the email using the SMTP server details and the email account password.
for k := range i.Mailto {

result := tpl.String()
Expand All @@ -42,10 +48,14 @@ func SendMail(i models.SmtpErr) {
m.SetHeader("To", i.Mailto[k])
m.SetHeader("Subject", i.Subject)
m.SetBody("text/html", result)

// Convert email port string to integer
intPort, _ := strconv.Atoi(allEnv.EmailPort)

// Create a dialer for the email server and authenticate using email credentials
d := gomail.NewDialer(allEnv.EmailServer, intPort, allEnv.EmailFrom, emailPass)

// Dial the email server and send the email
if err := d.DialAndSend(m); err != nil {
log.Println(err)

Expand All @@ -58,15 +68,20 @@ type error interface {
Error() string
}

// This function takes in the URL of the endpoint that caused the error, an error object with the error details, and a group name as strings, and creates a new alert in OpsGenie.
func OpsgenieCreateAlert(errorurl string, description error, group string) string {

// Create a message for the alert and get the environment variable for the OpsGenie API key.
downMessege := "Alert Endpint " + errorurl + " is Down"
allEnv := skyenv.GetEnv()
opsgenieSecret := allEnv.OpsgenieSecret

// Create an OpsGenie alert client with the specified API key
alertClient, err := alert.NewClient(&client.Config{
ApiKey: opsgenieSecret,
})

// Create a new alert with the specified details
createResult, _ := alertClient.Create(nil, &alert.CreateAlertRequest{
Message: downMessege,
Description: description.Error(),
Expand All @@ -81,41 +96,55 @@ func OpsgenieCreateAlert(errorurl string, description error, group string) strin
log.Printf("error: %s\n", err)
}

// Return the request ID of the created alert
return createResult.RequestId

}

// CheckAlertStatus retrieves the status of an OpsGenie alert with the specified request ID
func CheckAlertStatus(alertRequestId string) string {

// Create a new HTTP client.
apiclient := &http.Client{}

// Build the URL for the API call using the alert request ID.
url := "https://api.opsgenie.com/v2/alerts/requests/" + alertRequestId + "?identifierType=id"

// Retrieve the Opsgenie secret key from the environment variables.
allEnv := skyenv.GetEnv()
opsgenieSecret := allEnv.OpsgenieSecret
opsgenieSecretString := "GenieKey " + opsgenieSecret

// Create a new GET request with the Opsgenie secret key.
req, err := http.NewRequest("GET", url, nil)
if err != nil {
log.Println(err.Error())
}

req.Header.Add("Accept", "application/json")
req.Header.Add("Authorization", opsgenieSecretString)

// Send the HTTP request to Opsgenie API.
resp, err := apiclient.Do(req)
if err != nil {
log.Println(err.Error())
}
defer resp.Body.Close()

// Read the response body and unmarshal it into a struct.
bodyBytes, err := ioutil.ReadAll(resp.Body)
if err != nil {
log.Println(err.Error())
}
var responseObject models.OpsGenieAlertStatus
json.Unmarshal(bodyBytes, &responseObject)

// Create a new alert client using the Opsgenie secret key.
alertClient, err := alert.NewClient(&client.Config{
ApiKey: opsgenieSecret,
})

// Retrieve the alert status using the alert ID from the response.
getResult, err := alertClient.Get(nil, &alert.GetAlertRequest{
IdentifierType: alert.ALERTID,
IdentifierValue: responseObject.Data.AlertID,
Expand All @@ -124,5 +153,7 @@ func CheckAlertStatus(alertRequestId string) string {
if err != nil {
log.Printf("error: %s\n", err)
}

// Return the alert status.
return getResult.Status
}
14 changes: 0 additions & 14 deletions packages/api/api.go

This file was deleted.

Loading

0 comments on commit 19d966a

Please sign in to comment.