From 19d966ad4d22cb8491038b96f38bd4b8b7945057 Mon Sep 17 00:00:00 2001 From: sooraj-sky Date: Sun, 26 Feb 2023 13:50:32 +0530 Subject: [PATCH] closes #73; added comments, added option to enable features --- README.md | 61 +++++++++++++----------- cmd/main.go | 18 ++++++-- input.json | 46 ------------------ models/models.go | 8 +--- packages/alerts/alert.go | 33 ++++++++++++- packages/api/api.go | 14 ------ packages/dbops/db.go | 87 +++++++++++++++++++++++++++++------ packages/dns/skydns.go | 9 +++- packages/env/envexport.go | 13 ++++++ packages/httpres/trace.go | 48 +++++++++++++------ packages/httpserver/server.go | 20 -------- packages/jsonops/jsonops.go | 22 --------- packages/logger/sentry.go | 1 + packages/yamlops/yamlops.go | 17 ++++--- settings.yml | 10 ++-- 15 files changed, 225 insertions(+), 182 deletions(-) delete mode 100644 input.json delete mode 100644 packages/api/api.go delete mode 100644 packages/httpserver/server.go delete mode 100644 packages/jsonops/jsonops.go diff --git a/README.md b/README.md index 352412c..4d72854 100644 --- a/README.md +++ b/README.md @@ -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: @@ -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="" -``` -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 diff --git a/cmd/main.go b/cmd/main.go index 9de925d..995eb5c 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -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{ @@ -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 } diff --git a/input.json b/input.json deleted file mode 100644 index 0234762..0000000 --- a/input.json +++ /dev/null @@ -1,46 +0,0 @@ -[ - { - "url": "https://bing.com", - "timeout": 2000, - "skip_ssl": false, - "frequency" : 400, - "group": "prod" - }, - { - "url": "https://github.com", - "timeout": 3000, - "skip_ssl": false, - "frequency" : 5, - "group": "prod" - }, - { - "url": "https://stackoverflow.com", - "timeout": 2000, - "skip_ssl": false, - "frequency" : 300, - "group": "prod" - }, - { - "url": "https://edistrict.kerala.gov.in", - "timeout": 2000, - "skip_ssl": false, - "frequency" : 60, - "group": "prod" - }, - { - "url": "http://www.tanscst.nic.in", - "timeout": 2000, - "skip_ssl": false, - "frequency" : 100, - "group": "prod" - }, - { - "url": "http://www.tanssscst.nic.issn", - "timeout": 2000, - "skip_ssl": false, - "frequency" : 10, - "group": "prod" - } -] - - diff --git a/models/models.go b/models/models.go index 42bc6c0..ca8eb9c 100644 --- a/models/models.go +++ b/models/models.go @@ -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 { @@ -130,7 +127,6 @@ type AlertGroups struct { type AllEnvs struct { DnsServer string - Port string EmailPass string EmailFrom string EmailPort string diff --git a/packages/alerts/alert.go b/packages/alerts/alert.go index 30ce04f..5afc103 100644 --- a/packages/alerts/alert.go +++ b/packages/alerts/alert.go @@ -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() @@ -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) @@ -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(), @@ -81,17 +96,26 @@ 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()) @@ -99,12 +123,15 @@ func CheckAlertStatus(alertRequestId string) string { 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()) @@ -112,10 +139,12 @@ func CheckAlertStatus(alertRequestId string) string { 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, @@ -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 } diff --git a/packages/api/api.go b/packages/api/api.go deleted file mode 100644 index 15f45af..0000000 --- a/packages/api/api.go +++ /dev/null @@ -1,14 +0,0 @@ -package api - -import ( - "fmt" - "net/http" -) - -func HomeLink(w http.ResponseWriter, r *http.Request) { - fmt.Fprintf(w, "Welcome to sky-meter") -} - -func SelfStatusLink(w http.ResponseWriter, r *http.Request) { - fmt.Fprintf(w, "Status OK") -} diff --git a/packages/dbops/db.go b/packages/dbops/db.go index 9283eff..16e14db 100644 --- a/packages/dbops/db.go +++ b/packages/dbops/db.go @@ -11,10 +11,12 @@ import ( "gorm.io/gorm" ) +// Define an interface named error to avoid name collision with the built-in error interface type error interface { Error() string } +// Perform initial migrations for the database tables func InitialMigration(db *gorm.DB) { db.AutoMigrate(&models.AllEndpoints{}) db.AutoMigrate(&models.HttpOutput{}) @@ -22,10 +24,13 @@ func InitialMigration(db *gorm.DB) { db.AutoMigrate(&models.AlertGroups{}) } +// Insert URLs and associated data into the database func InsertUrlsToDb(db *gorm.DB, endpoints models.UserInput) { var urlCheck models.AllEndpoints var urlsId models.AllEndpoints var Groups models.AlertGroups + + // Loop through each domain and check if it already exists in the database; if it does not, create it for i := 0; i < len(endpoints.Domains); i++ { db.Where("URL=?", endpoints.Domains[i].Name).Find(&urlCheck) if urlCheck.CreatedAt == 0 && urlCheck.URL != endpoints.Domains[i].Name { @@ -34,6 +39,7 @@ func InsertUrlsToDb(db *gorm.DB, endpoints models.UserInput) { urlCheck = urlsId } + // Loop through each group and its associated emails, and create them if they do not exist in the database for i := range endpoints.Groups { db.Where("NAME=?", endpoints.Groups[i].Name).Find(&Groups) for k := range endpoints.Groups[i].Emails { @@ -46,52 +52,93 @@ func InsertUrlsToDb(db *gorm.DB, endpoints models.UserInput) { } -func GetUrlFrequency(db *gorm.DB) { +// Check the frequency of each URL in the database, and send alerts if necessary +func GetUrlFrequency(db *gorm.DB, endpoints models.UserInput) { var urlsToCheck []models.AllEndpoints var urlsId []models.AllEndpoints var alertStatus models.OpsgenieAlertData var GroupsEmailIds []models.AlertGroups var Empty []models.AlertGroups + // Find all URLs in the database db.Find(&urlsToCheck) + + // Loop through each URL for i := 0; i < len(urlsToCheck); i++ { + + // Retrieve the URL by ID db.First(&urlsId, urlsToCheck[i].ID) + + // Check if the URL is active if urlsToCheck[i].Active { + + // If the URL has not yet been checked, update the "next run" field and check it if urlsToCheck[i].NextRun == 0 { db.Model(&urlsId).Where("id = ?", urlsToCheck[i].ID).Update("next_run", urlsToCheck[i].Frequency) + + // Call the URL and retrieve the HTTP output and status code httpOutput, HttpStatusCode, err := httpreponser.CallEndpoint(urlsToCheck[i].URL, urlsToCheck[i].Timeout, urlsToCheck[i].SkipSsl) + + // If an error occurred, send alerts if err != nil { + + // Retrieve any existing alerts for the URL db.First(&alertStatus, "url = ?", urlsToCheck[i].URL) + + // Find alert groups for the URL db.Where("Name=?", urlsToCheck[i].Group).Find(&GroupsEmailIds) var emailIds []string for _, group := range GroupsEmailIds { emailIds = append(emailIds, group.Email) } - log.Println(GroupsEmailIds, "email") - + // Check if there is already an existing alert for the URL if alertStatus.URL == urlsToCheck[i].URL { dt := time.Now() - AlertStatus := skyalerts.CheckAlertStatus(alertStatus.RequestId) - if (AlertStatus == "closed") || (alertStatus.Error != err.Error()) { - alertReqId := skyalerts.OpsgenieCreateAlert(urlsToCheck[i].URL, err, urlsToCheck[i].Group) - db.Model(&alertStatus).Where("url = ?", urlsToCheck[i].URL).Update("request_id", alertReqId) + + // Send Opsgenie Notification + if endpoints.Opegenie.Enabled { + AlertStatus := skyalerts.CheckAlertStatus(alertStatus.RequestId) + if (AlertStatus == "closed") || (alertStatus.Error != err.Error()) { + alertReqId := skyalerts.OpsgenieCreateAlert(urlsToCheck[i].URL, err, urlsToCheck[i].Group) + db.Model(&alertStatus).Where("url = ?", urlsToCheck[i].URL).Update("request_id", alertReqId) + } else { + alertReqId := "Opegenie-disabled" + db.Model(&alertStatus).Where("url = ?", urlsToCheck[i].URL).Update("request_id", alertReqId) + } + d := models.SmtpErr{urlsToCheck[i].URL, "webiste is Down", dt, err.Error(), emailIds} - skyalerts.SendMail(d) + // Send Email Notification + if endpoints.Email.Enabled { + skyalerts.SendMail(d) + } + } + + // Reset alert groups GroupsEmailIds = Empty } else { + // If there is no existing alert for the URL, create a new one dts := time.Now() db.Create(&models.HttpOutput{OutputData: httpOutput, URL: urlsToCheck[i].URL, StatusCode: HttpStatusCode, Error: err.Error()}) d := models.SmtpErr{urlsToCheck[i].URL, "webiste is Down", dts, err.Error(), emailIds} + if endpoints.Opegenie.Enabled { + alertReqId := skyalerts.OpsgenieCreateAlert(urlsToCheck[i].URL, err, urlsToCheck[i].Group) + db.Create(&models.OpsgenieAlertData{URL: urlsToCheck[i].URL, RequestId: alertReqId, Error: err.Error(), Active: true}) + db.Create(&models.HttpOutput{OutputData: httpOutput, URL: urlsToCheck[i].URL, StatusCode: HttpStatusCode, Error: err.Error()}) + } else { + alertReqId := "Opegenie-disabled" + db.Create(&models.OpsgenieAlertData{URL: urlsToCheck[i].URL, RequestId: alertReqId, Error: err.Error(), Active: true}) + db.Create(&models.HttpOutput{OutputData: httpOutput, URL: urlsToCheck[i].URL, StatusCode: HttpStatusCode, Error: err.Error()}) - alertReqId := skyalerts.OpsgenieCreateAlert(urlsToCheck[i].URL, err, urlsToCheck[i].Group) - db.Create(&models.OpsgenieAlertData{URL: urlsToCheck[i].URL, RequestId: alertReqId, Error: err.Error(), Active: true}) - db.Create(&models.HttpOutput{OutputData: httpOutput, URL: urlsToCheck[i].URL, StatusCode: HttpStatusCode, Error: err.Error()}) + } - skyalerts.SendMail(d) + // Send Email Notification + if endpoints.Email.Enabled { + skyalerts.SendMail(d) + } } } else { @@ -107,16 +154,28 @@ func GetUrlFrequency(db *gorm.DB) { } } +// This function removes old entries from the database based on the input provided. +// It takes a database object and user input object as parameters. func RemoveOldEntry(db *gorm.DB, endpoints models.UserInput) { + + // Retrieve all endpoints from the database. var urlCheck []models.AllEndpoints db.Find(&urlCheck) var urlsId models.AllEndpoints - + // Iterate through all endpoints from the database. for i := 0; i < len(urlCheck); i++ { + + // Initialize a variable to keep track of how many endpoints are found. var findCount int + + // Iterate through all domains in the user input object. for m := range endpoints.Domains { + + // Check if the domain from user input is present in the database. if endpoints.Domains[m].Name == urlCheck[i].URL { log.Println("found URL", urlCheck[i].URL) + + // If the endpoint is inactive, update its status to active. if urlCheck[i].Active != true { db.Model(&urlsId).Where("url = ?", urlCheck[i].URL).Update("Active", true) } @@ -124,6 +183,8 @@ func RemoveOldEntry(db *gorm.DB, endpoints models.UserInput) { findCount = findCount + 1 } } + + // If the endpoint is not found in the user input object, update its status to inactive. if findCount >= len(endpoints.Domains) { log.Println(urlCheck[i].URL, "Not found in input.json, removing the check") db.Model(&urlsId).Where("url = ?", urlCheck[i].URL).Update("Active", false) diff --git a/packages/dns/skydns.go b/packages/dns/skydns.go index 7f3c695..f73bbf5 100644 --- a/packages/dns/skydns.go +++ b/packages/dns/skydns.go @@ -6,16 +6,22 @@ import ( "time" ) -// Create a custom Resolver that uses a specific DNS server IP +// CustomResolver returns a custom resolver that resolves DNS queries using the specified DNS server. func CustomResolver(dnsServer string) *net.Resolver { return &net.Resolver{ + + // create a new net.Resolver with PreferGo set to true PreferGo: true, Dial: func(ctx context.Context, network, address string) (net.Conn, error) { + + // create a new net.Dialer with a timeout of 10 seconds and a custom resolver that uses the specified DNS server dialer := net.Dialer{ Timeout: 10 * time.Second, Resolver: &net.Resolver{ PreferGo: true, Dial: func(ctx context.Context, network, address string) (net.Conn, error) { + + // create a new net.Dialer with a timeout of 10 seconds and DualStack set to true, and use it to dial the specified DNS server return (&net.Dialer{ Timeout: 10 * time.Second, DualStack: true, @@ -23,6 +29,7 @@ func CustomResolver(dnsServer string) *net.Resolver { }, }, } + // use the dialer to dial the specified network and address return dialer.DialContext(ctx, network, address) }, } diff --git a/packages/env/envexport.go b/packages/env/envexport.go index 7ae469f..f72f201 100644 --- a/packages/env/envexport.go +++ b/packages/env/envexport.go @@ -6,6 +6,7 @@ import ( "os" "reflect" models "sky-meter/models" + yamlops "sky-meter/packages/yamlops" ) // To add a new env variable, add that variable to models.AllEnvs struct. @@ -35,6 +36,18 @@ func InitEnv() { var envStatus []string + endpoints := yamlops.InputYml() + + if endpoints.Opegenie.Enabled != true { + os.Setenv("OpsgenieSecret", "tmp-opsgenie-key") + } + if endpoints.Email.Enabled != true { + os.Setenv("EmailPass", "tmp-key") + os.Setenv("EmailFrom", "tmp-key") + os.Setenv("EmailPort", "tmp-key") + os.Setenv("EmailServer", "tmp-key") + } + for i := range envNames { envValue := os.Getenv(envNames[i]) if envValue == "" { diff --git a/packages/httpres/trace.go b/packages/httpres/trace.go index 1a54a18..4784801 100644 --- a/packages/httpres/trace.go +++ b/packages/httpres/trace.go @@ -36,86 +36,106 @@ func GetHttpdata(url string, timeout time.Duration, SkipSsl bool) (httpdata []by return data, res.StatusCode, err } +// client returns an instance of *http.Client with the given timeout and SSL skip settings. func client(timeout time.Duration, SkipSsl bool) *http.Client { + // The transport function is called to create the Transport object for the client. return &http.Client{ - Transport: transport(SkipSsl), - Timeout: time.Duration(timeout * time.Millisecond), + Transport: transport(SkipSsl), // If SkipSsl is true, the Transport object is created with InsecureSkipVerify set to true. + Timeout: time.Duration(timeout * time.Millisecond), // The Timeout field of the client is set to the given timeout value. } + // The returned client should be used to make HTTP requests to remote servers. } +// transport creates a new http.Transport instance with the provided SkipSsl flag +// If SkipSsl is true, DisableKeepAlives will be set to true to disable keep-alive connections +// TLSClientConfig will be set using the tlsConfig() function func transport(SkipSsl bool) *http.Transport { return &http.Transport{ DisableKeepAlives: SkipSsl, - TLSClientConfig: tlsConfig(), + TLSClientConfig: tlsConfig(SkipSsl), } } -func tlsConfig() *tls.Config { +func tlsConfig(SkipSsl bool) *tls.Config { + // Create a new tls.Config struct and initialize its fields return &tls.Config{ - InsecureSkipVerify: true, + // SSL verification + InsecureSkipVerify: SkipSsl, } } func trace() (*httptrace.ClientTrace, *models.Debug) { + + // Set up custom DNS resolver using DNS server from environment variables. allEnv := skyenv.GetEnv() - //DNS settings dnsServer := allEnv.DnsServer resolver := skydns.CustomResolver(dnsServer) fmt.Sprintln(resolver) + + // Create a new Debug object. d := &models.Debug{} + // Create a new ClientTrace object with callback functions for different stages of the HTTP request/response cycle. t := &httptrace.ClientTrace{ + // Callback function for DNS start. DNSStart: func(info httptrace.DNSStartInfo) { t := time.Now().UTC().String() - //log.Println(t, "dns start") d.DNS.Start = t d.DNS.Host = info.Host }, + // Callback function for DNS end. DNSDone: func(info httptrace.DNSDoneInfo) { t := time.Now().UTC().String() - //log.Println(t, "dns end") d.DNS.End = t d.DNS.Address = info.Addrs d.DNS.Error = info.Err }, + // Callback function for dial start. ConnectStart: func(network, addr string) { t := time.Now().UTC().String() - //log.Println(t, "dial start") d.Dial.Start = t }, + // Callback function for dial end. ConnectDone: func(network, addr string, err error) { t := time.Now().UTC().String() - //log.Println(t, "dial end") d.Dial.End = t }, + // Callback function for connection time. GotConn: func(connInfo httptrace.GotConnInfo) { t := time.Now().UTC().String() - //log.Println(t, "conn time") d.Connection.Time = t }, + // Callback function for writing all request headers. WroteHeaders: func() { t := time.Now().UTC().String() - //log.Println(t, "wrote all request headers") d.WroteAllRequestHeaders.Time = t }, + // Callback function for writing all request. WroteRequest: func(wr httptrace.WroteRequestInfo) { t := time.Now().UTC().String() - //log.Println(t, "wrote all request") d.WroteAllRequest.Time = t }, + // Callback function for first received response byte. GotFirstResponseByte: func() { t := time.Now().UTC().String() - //log.Println(t, "first received response byte") d.FirstReceivedResponseByte.Time = t }, } + // Return the ClientTrace object and the Debug object. return t, d } +// CallEndpoint calls an HTTP endpoint with the given URL and timeout, and returns the response body, status code, and any errors encountered. func CallEndpoint(endpoint interface{}, timeout int, SkipSsl bool) ([]byte, int, error) { + + // Convert the endpoint parameter to a string url, _ := endpoint.(string) + + // Call GetHttpdata to retrieve the HTTP response data, status code, and error httpresdata, statusCode, err := GetHttpdata(url, time.Duration(timeout), SkipSsl) + + // Return the HTTP response data, status code, and error return httpresdata, statusCode, err } diff --git a/packages/httpserver/server.go b/packages/httpserver/server.go deleted file mode 100644 index 7eaaa09..0000000 --- a/packages/httpserver/server.go +++ /dev/null @@ -1,20 +0,0 @@ -package htttpserver - -import ( - "log" - "net/http" - - "github.com/gorilla/mux" - api "sky-meter/packages/api" - skyenv "sky-meter/packages/env" -) - -func InitServer() { - allEnv := skyenv.GetEnv() - port := allEnv.Port - log.Println("listening on port", port) - router := mux.NewRouter().StrictSlash(true) - router.HandleFunc("/", api.HomeLink) - router.HandleFunc("/health", api.SelfStatusLink) - log.Fatal(http.ListenAndServe(":"+port, router)) -} diff --git a/packages/jsonops/jsonops.go b/packages/jsonops/jsonops.go deleted file mode 100644 index 0bb4d90..0000000 --- a/packages/jsonops/jsonops.go +++ /dev/null @@ -1,22 +0,0 @@ -package jsonops - -import ( - "encoding/json" - "fmt" - "io/ioutil" - "os" - - models "sky-meter/models" -) - -func InputJson() models.JsonInput { - jsonFile, err := os.Open("input.json") - if err != nil { - fmt.Println(err) - } - defer jsonFile.Close() - byteValue, _ := ioutil.ReadAll(jsonFile) - var endpoints models.JsonInput - json.Unmarshal(byteValue, &endpoints) - return endpoints -} diff --git a/packages/logger/sentry.go b/packages/logger/sentry.go index 4e18087..6beb1eb 100644 --- a/packages/logger/sentry.go +++ b/packages/logger/sentry.go @@ -7,6 +7,7 @@ import ( skyenv "sky-meter/packages/env" ) +// The function SentryInit initializes the Sentry error tracking service. func SentryInit() { allEnv := skyenv.GetEnv() mode := allEnv.Mode diff --git a/packages/yamlops/yamlops.go b/packages/yamlops/yamlops.go index 5f05fd1..ee41c4c 100644 --- a/packages/yamlops/yamlops.go +++ b/packages/yamlops/yamlops.go @@ -4,30 +4,35 @@ import ( "gopkg.in/yaml.v2" "io/ioutil" "log" - "os" "path/filepath" models "sky-meter/models" - "strconv" ) +// This is a Go function named InputYml that returns a models.UserInput object. func InputYml() models.UserInput { + + // Get the absolute path of the settings.yml file in the current directory. filename, _ := filepath.Abs("./settings.yml") + + // Read the contents of the settings.yml file into a byte slice. yamlFile, err := ioutil.ReadFile(filename) + // If an error occurs while reading the file, log it. if err != nil { log.Println(err) } + // Create a new UserInput object to unmarshal the YAML into. var config models.UserInput + // Unmarshal the YAML data into the UserInput object. err = yaml.Unmarshal(yamlFile, &config) + + // If an error occurs while unmarshaling, log it. if err != nil { log.Println(err) } - os.Setenv("emailFrom", config.Email[0].Sender) - os.Setenv("emailServer", config.Email[0].Server) - os.Setenv("EmailPort", strconv.Itoa(config.Email[0].Port)) - + // Return the UserInput object. return config } diff --git a/settings.yml b/settings.yml index 5412c1d..ca238db 100644 --- a/settings.yml +++ b/settings.yml @@ -1,10 +1,7 @@ opegenie: -- enabled: false + enabled: false email: -- enabled: true - server: smtp.gmail.com - port: 587 - sender: linux.sooraj@gmail.com + enabled: true groups: - name: prod @@ -35,10 +32,9 @@ domains: skip_ssl: false frequency: 60 group: prod - - name: https://githcccubs.com enabled: true timeout: 10 skip_ssl: false - frequency: 60 + frequency: 70 group: prod \ No newline at end of file