From 7846420fa70994802fd6ba07d6e368ce3312c945 Mon Sep 17 00:00:00 2001 From: 0xdcarns Date: Tue, 25 Jan 2022 11:00:56 -0500 Subject: [PATCH] added timer hooks --- controllers/controller.go | 4 +- controllers/logger.go | 23 ----------- controllers/network.go | 4 +- controllers/server_util.go | 13 +++--- database/database.go | 2 +- {serverctl => logic}/telemetry.go | 68 +++++++++---------------------- logic/timer.go | 54 ++++++++++++++++++++++++ main.go | 4 +- serverctl/serverq.go | 29 ------------- 9 files changed, 86 insertions(+), 115 deletions(-) delete mode 100644 controllers/logger.go rename {serverctl => logic}/telemetry.go (66%) create mode 100644 logic/timer.go delete mode 100644 serverctl/serverq.go diff --git a/controllers/controller.go b/controllers/controller.go index 008d517f..e2c5f007 100644 --- a/controllers/controller.go +++ b/controllers/controller.go @@ -15,6 +15,7 @@ import ( "github.com/gravitl/netmaker/servercfg" ) +// HttpHandlers - handler functions for REST interactions var HttpHandlers = []interface{}{ nodeHandlers, userHandlers, @@ -23,7 +24,6 @@ var HttpHandlers = []interface{}{ fileHandlers, serverHandlers, extClientHandlers, - loggerHandlers, } // HandleRESTRequests - handles the rest requests @@ -64,7 +64,7 @@ func HandleRESTRequests(wg *sync.WaitGroup) { // After receiving CTRL+C Properly stop the server logger.Log(0, "Stopping the REST server...") - srv.Shutdown(context.TODO()) logger.Log(0, "REST Server closed.") logger.DumpFile(fmt.Sprintf("data/netmaker.log.%s", time.Now().Format(logger.TimeFormatDay))) + srv.Shutdown(context.TODO()) } diff --git a/controllers/logger.go b/controllers/logger.go deleted file mode 100644 index 81f6e242..00000000 --- a/controllers/logger.go +++ /dev/null @@ -1,23 +0,0 @@ -package controller - -import ( - "fmt" - "net/http" - "time" - - "github.com/gorilla/mux" - "github.com/gravitl/netmaker/logger" -) - -func loggerHandlers(r *mux.Router) { - r.HandleFunc("/api/logs", securityCheck(true, http.HandlerFunc(getLogs))).Methods("GET") -} - -func getLogs(w http.ResponseWriter, r *http.Request) { - var currentTime = time.Now().Format(logger.TimeFormatDay) - var currentFilePath = fmt.Sprintf("data/netmaker.log.%s", currentTime) - logger.DumpFile(currentFilePath) - logger.ResetLogs() - w.WriteHeader(http.StatusOK) - w.Write([]byte(logger.Retrieve(currentFilePath))) -} diff --git a/controllers/network.go b/controllers/network.go index 1c78b534..dcb5eecd 100644 --- a/controllers/network.go +++ b/controllers/network.go @@ -182,8 +182,8 @@ func updateNetworkNodeLimit(w http.ResponseWriter, r *http.Request) { json.NewEncoder(w).Encode(network) } -//Delete a network -//Will stop you if there's any nodes associated +// Delete a network +// Will stop you if there's any nodes associated func deleteNetwork(w http.ResponseWriter, r *http.Request) { // Set header w.Header().Set("Content-Type", "application/json") diff --git a/controllers/server_util.go b/controllers/server_util.go index 84cd4566..e2cbb273 100644 --- a/controllers/server_util.go +++ b/controllers/server_util.go @@ -4,22 +4,19 @@ import ( "github.com/gravitl/netmaker/logger" "github.com/gravitl/netmaker/logic" "github.com/gravitl/netmaker/servercfg" - "github.com/gravitl/netmaker/serverctl" ) func runServerPeerUpdate(network string, shouldPeerUpdate bool) error { - if servercfg.Telemetry() == "on" { - err := serverctl.TelemetryCheckpoint() - if err != nil { - logger.Log(1, "failed to send telemetry:", err.Error()) - } + err := logic.TimerCheckpoint() + if err != nil { + logger.Log(3, "error occurred on timer,", err.Error()) } if servercfg.IsClientMode() != "on" { return nil } - var currentServerNodeID, err = logic.GetNetworkServerNodeID(network) + var currentServerNodeID, getErr = logic.GetNetworkServerNodeID(network) if err != nil { - return err + return getErr } var currentServerNode, currErr = logic.GetNodeByID(currentServerNodeID) if currErr != nil { diff --git a/database/database.go b/database/database.go index b2769d1f..dece51b8 100644 --- a/database/database.go +++ b/database/database.go @@ -206,7 +206,7 @@ func initializeUUID() error { return nil } telemetry := models.Telemetry{UUID: uuid.NewString()} - telJSON, err := json.Marshal(telemetry) + telJSON, err := json.Marshal(&telemetry) if err != nil { return err } diff --git a/serverctl/telemetry.go b/logic/telemetry.go similarity index 66% rename from serverctl/telemetry.go rename to logic/telemetry.go index fd64492c..345b6cfa 100644 --- a/serverctl/telemetry.go +++ b/logic/telemetry.go @@ -1,68 +1,45 @@ -package serverctl +package logic import ( "encoding/json" "time" "github.com/gravitl/netmaker/database" - "github.com/gravitl/netmaker/logger" - "github.com/gravitl/netmaker/logic" "github.com/gravitl/netmaker/models" "github.com/gravitl/netmaker/servercfg" "github.com/posthog/posthog-go" ) -// POSTHOG_PUB_KEY - Key for sending data to PostHog -const POSTHOG_PUB_KEY = "phc_1vEXhPOA1P7HP5jP2dVU9xDTUqXHAelmtravyZ1vvES" +// posthog_pub_key - Key for sending data to PostHog +const posthog_pub_key = "phc_1vEXhPOA1P7HP5jP2dVU9xDTUqXHAelmtravyZ1vvES" -// POSTHOG_ENDPOINT - Endpoint of PostHog server -const POSTHOG_ENDPOINT = "https://app.posthog.com" - -// TELEMETRY_HOURS_BETWEEN_SEND - How long to wait before sending telemetry to server (24 hours) -const TELEMETRY_HOURS_BETWEEN_SEND = 24 - -// TelemetryCheckpoint - Checks if 24 hours has passed since telemetry was last sent. If so, sends telemetry data to posthog -func TelemetryCheckpoint() error { - - // if telemetry is turned off, return without doing anything - if servercfg.Telemetry() == "off" { - return nil - } - // get the telemetry record in the DB, which contains a timestamp - telRecord, err := fetchTelemetryRecord() - if err != nil { - return err - } - sendtime := time.Unix(telRecord.LastSend, 0).Add(time.Hour * time.Duration(TELEMETRY_HOURS_BETWEEN_SEND)) - // can set to 2 minutes for testing - //sendtime := time.Unix(telRecord.LastSend, 0).Add(time.Minute * 2) - enoughTimeElapsed := time.Now().After(sendtime) - // if more than 24 hours has elapsed, send telemetry to posthog - if enoughTimeElapsed { - err = sendTelemetry(telRecord.UUID) - if err != nil { - logger.Log(1, err.Error()) - } - } - return nil -} +// posthog_endpoint - Endpoint of PostHog server +const posthog_endpoint = "https://app.posthog.com" // sendTelemetry - gathers telemetry data and sends to posthog -func sendTelemetry(serverUUID string) error { +func sendTelemetry() { + if servercfg.Telemetry() == "off" { + return + } + + var telRecord, err = fetchTelemetryRecord() + if err != nil { + return + } // get telemetry data d, err := fetchTelemetryData() if err != nil { - return err + return } - client, err := posthog.NewWithConfig(POSTHOG_PUB_KEY, posthog.Config{Endpoint: POSTHOG_ENDPOINT}) + client, err := posthog.NewWithConfig(posthog_pub_key, posthog.Config{Endpoint: posthog_endpoint}) if err != nil { - return err + return } defer client.Close() // send to posthog - err = client.Enqueue(posthog.Capture{ - DistinctId: serverUUID, + client.Enqueue(posthog.Capture{ + DistinctId: telRecord.UUID, Event: "daily checkin", Properties: posthog.NewProperties(). Set("nodes", d.Nodes). @@ -78,11 +55,6 @@ func sendTelemetry(serverUUID string) error { Set("k8s", d.Count.K8S). Set("version", d.Version), }) - if err != nil { - return err - } - //set telemetry timestamp for server, restarts 24 hour cycle - return setTelemetryTimestamp(serverUUID) } // fetchTelemetry - fetches telemetry data: count of various object types in DB @@ -93,7 +65,7 @@ func fetchTelemetryData() (telemetryData, error) { data.Users = getDBLength(database.USERS_TABLE_NAME) data.Networks = getDBLength(database.NETWORKS_TABLE_NAME) data.Version = servercfg.GetVersion() - nodes, err := logic.GetAllNodes() + nodes, err := GetAllNodes() if err == nil { data.Nodes = len(nodes) data.Count = getClientCount(nodes) diff --git a/logic/timer.go b/logic/timer.go new file mode 100644 index 00000000..6711b8e8 --- /dev/null +++ b/logic/timer.go @@ -0,0 +1,54 @@ +package logic + +import ( + "fmt" + "time" + + "github.com/gravitl/netmaker/logger" +) + +// timeHooks - functions to run once a day, functions must take no parameters +var timeHooks = []interface{}{ + loggerDump, + sendTelemetry, +} + +func loggerDump() { + logger.DumpFile(fmt.Sprintf("data/netmaker.log.%s", time.Now().Format(logger.TimeFormatDay))) +} + +// TIMER_HOURS_BETWEEN_RUN - How long to wait before sending telemetry to server (24 hours) +const TIMER_HOURS_BETWEEN_RUN = 24 + +// AddHook - adds a hook function to run every 24hrs +func AddHook(ifaceToAdd interface{}) { + timeHooks = append(timeHooks, ifaceToAdd) +} + +// runHooks - runs the functions currently in the timeHooks data structure +func runHooks() { + for _, hook := range timeHooks { + hook.(func())() + } +} + +// TimerCheckpoint - Checks if 24 hours has passed since telemetry was last sent. If so, sends telemetry data to posthog +func TimerCheckpoint() error { + + // get the telemetry record in the DB, which contains a timestamp + telRecord, err := fetchTelemetryRecord() + if err != nil { + return err + } + sendtime := time.Unix(telRecord.LastSend, 0).Add(time.Hour * time.Duration(TIMER_HOURS_BETWEEN_RUN)) + // can set to 2 minutes for testing + // sendtime := time.Unix(telRecord.LastSend, 0).Add(time.Minute * 2) + enoughTimeElapsed := time.Now().After(sendtime) + // if more than 24 hours has elapsed, send telemetry to posthog + if enoughTimeElapsed { + // run any time hooks + runHooks() + } + // set telemetry timestamp for server, restarts 24 hour cycle + return setTelemetryTimestamp(telRecord.UUID) +} diff --git a/main.go b/main.go index eba2c60f..01ace1da 100644 --- a/main.go +++ b/main.go @@ -41,9 +41,9 @@ func initialize() { // Client Mode Prereq Check } logger.Log(0, "database successfully connected") - err = serverctl.TelemetryCheckpoint() + err = logic.TimerCheckpoint() if err != nil { - logger.Log(1, "Failed to send telemetry: ", err.Error()) + logger.Log(1, "Timer error occurred: ", err.Error()) } var authProvider = auth.InitializeAuthProvider() if authProvider != "" { diff --git a/serverctl/serverq.go b/serverctl/serverq.go deleted file mode 100644 index 132846d7..00000000 --- a/serverctl/serverq.go +++ /dev/null @@ -1,29 +0,0 @@ -package serverctl - -import ( - "fmt" - - "github.com/gravitl/netmaker/models" -) - -// ServerQueue - holds data to be updated across the server -var ServerQueue chan models.ServerUpdateData - -func init() { - ServerQueue = make(chan models.ServerUpdateData, 100) -} - -// Push - Pushes ServerUpdateData to be used later -func Push(serverData models.ServerUpdateData) { - ServerQueue <- serverData -} - -// Pop - fetches first available data from queue -func Pop() (models.ServerUpdateData, error) { - select { - case serverData := <-ServerQueue: - return serverData, nil - default: - return models.ServerUpdateData{}, fmt.Errorf("empty server queue") - } -}