search/exceptionless/exceptionless.go

218 lines
5.5 KiB
Go
Raw Normal View History

2022-10-17 04:14:39 +00:00
package exceptionless
import (
"encoding/json"
"fmt"
"math/rand"
"time"
"github.com/google/uuid"
)
var config map[string]interface{} = nil
// Config type defines the client configuration structure
type Config struct {
ApiKey string
ServerURL string
ProgramName string
UpdateSettingsWhenIdleInterval int32
}
var conf *Config
func Init(config *Config) {
conf = config
if conf == nil {
return
}
if conf.ApiKey != "" && conf.UpdateSettingsWhenIdleInterval > 0 {
poll()
}
}
// GetConfig returns the project configuration
func GetConfig() map[string]interface{} {
return config
}
// SubmitEvent sends log events to Exceptionless
func SubmitEvent(eventBody string) string {
if conf.ApiKey == "" {
return ""
}
resp := Post("events", eventBody, conf.ApiKey)
return resp
}
func poll() {
r := rand.New(rand.NewSource(99))
c := time.Tick(10 * time.Second)
for _ = range c {
resp := Get("projects/config", conf.ApiKey)
config = resp
jitter := time.Duration(r.Int31n(conf.UpdateSettingsWhenIdleInterval)) * time.Millisecond
time.Sleep(jitter)
}
}
// Event is the main model for events
type Event struct {
EventType string `json:"type"`
Source string `json:"source,omitempty"`
Date string `json:"date,omitempty"`
Tags []string `json:"tags,omitempty"`
Message string `json:"message,omitempty"`
Geo string `json:"geo,omitempty"`
Value uint `json:"value,omitempty"`
Data map[string]interface{} `json:"data,omitempty"`
ReferenceID string `json:"reference_id,omitempty"`
Count uint `json:"count,omitempty"`
}
// GetBaseEvent returns an empty Event struct that can be built into any type of event.
func GetBaseEvent(eventType string, message string, date string) Event {
return Event{
EventType: eventType,
Message: message,
Date: date,
}
}
// AddSource adds a string value source to an event
func AddSource(event Event, source string) Event {
event.Source = source
return event
}
// AddTags adds a string array of tags for the event
func AddTags(event Event, tags []string) Event {
event.Tags = tags
return event
}
// AddGeo adds the lat and long location of the user the event impacted
func AddGeo(event Event, geo string) Event {
event.Geo = geo
return event
}
// AddValue adds an arbitrary number value to the event
func AddValue(event Event, value uint) Event {
event.Value = value
return event
}
// AddReferenceID adds an indentifier to later refer to this event
func AddReferenceID(event Event, referenceID uuid.UUID) Event {
event.ReferenceID = referenceID.String()
return event
}
// AddCount adds a number to help track the number of times the event has occurred
func AddCount(event Event, count uint) Event {
event.Count = count
return event
}
func AddLogLevel(event Event, level string) Event {
var updatedEvent Event
if event.Data != nil {
event.Data["@level"] = level
updatedEvent = event
} else {
data := map[string]interface{}{}
data["@level"] = level
updatedEvent = AddData(event, data)
}
return updatedEvent
}
// AddData adds a string mapping to create a data object of additional values
func AddData(event Event, data map[string]interface{}) Event {
event.Data = data
return event
}
func SubmitAppError(funcName string, proc string, reqid *string, err error) string {
referenceID := uuid.Must(uuid.NewUUID()).String()
if reqid != nil {
referenceID = *reqid
}
errorMap := map[string]interface{}{}
errorMap["function"] = funcName
errorMap["type"] = "error"
errorMap["message"] = err.Error()
errorMap["date"] = time.Now().Format(time.RFC3339)
data := map[string]interface{}{}
data["@simple_error"] = errorMap
var event = Event{
EventType: "error",
Message: fmt.Sprintf("%s - %s", funcName, proc),
Data: data,
ReferenceID: referenceID,
Source: conf.ProgramName,
}
json, err := json.Marshal(event)
if err != nil {
return err.Error()
}
resp := SubmitEvent(string(json))
return resp
}
// SubmitError is a convenience wrapper to quickly build and submit an error
func SubmitError(err error) string {
if conf.UpdateSettingsWhenIdleInterval > 0 {
GetConfig()
}
referenceID := uuid.Must(uuid.NewUUID())
errorMap := map[string]interface{}{}
errorMap["type"] = "error"
errorMap["message"] = err.Error()
errorMap["date"] = time.Now().Format(time.RFC3339)
data := map[string]interface{}{}
data["@simple_error"] = errorMap
var mainEvent = Event{
EventType: "error",
Message: err.Error(),
Data: data,
ReferenceID: referenceID.String(),
}
json, err := json.Marshal(mainEvent)
if err != nil {
fmt.Println(err)
return err.Error()
}
resp := SubmitEvent(string(json))
return resp
}
func SubmitLog(message string, level string) string {
referenceID := uuid.Must(uuid.NewUUID())
if conf.UpdateSettingsWhenIdleInterval > 0 {
config := GetConfig()
fmt.Println(config)
// We are stripping out info accoring to the config settings
// We would also prevent logs of levels below the log level set by the settings
}
var event Event
date := time.Now().Format(time.RFC3339)
event = GetBaseEvent("log", message, date)
event = AddReferenceID(event, referenceID)
data := map[string]interface{}{}
data["@level"] = level
event = AddData(event, data)
json, err := json.Marshal(event)
if err != nil {
fmt.Println(err)
return err.Error()
}
resp := SubmitEvent(string(json))
return resp
}