sermoni

"Service monitor" / cronjob status service
Log | Files | Refs

events.go (4044B)


      1 package events
      2 
      3 import (
      4 	"errors"
      5 	"fmt"
      6 	"log"
      7 	"sermoni/internal/database"
      8 
      9 	"go.etcd.io/bbolt"
     10 )
     11 
     12 var (
     13 	keyEventID        = []byte("id")
     14 	keyEventService   = []byte("service")
     15 	keyEventTimestamp = []byte("timestamp")
     16 	keyEventStatus    = []byte("status")
     17 	keyEventTitle     = []byte("title")
     18 	keyEventDetails   = []byte("details")
     19 )
     20 
     21 // Event contains data sent to sermoni from a service
     22 type Event struct {
     23 	ID          uint64 `json:"id"`
     24 	Service     uint64 `json:"serviceid"`
     25 	Timestamp   uint64 `json:"timestamp"`
     26 	Status      string `json:"status"`
     27 	Title       string `json:"title"`
     28 	Details     string `json:"details"`
     29 	ServiceName string `json:"service"` // Name of service - not persisted to DB
     30 }
     31 
     32 // GetAll returns all events in the database
     33 func GetAll() []*Event {
     34 	events := []*Event{}
     35 	db := database.GetDB()
     36 	err := db.View(func(tx *bbolt.Tx) error {
     37 		b := tx.Bucket(database.BucketKeyEvents)
     38 		if b == nil {
     39 			log.Panic("The events bucket does not exist")
     40 		}
     41 		// ForEach doesn't return buckets (nil instead), so only the key is useful
     42 		return b.ForEach(func(id, _ []byte) error {
     43 			eb := b.Bucket(id)
     44 			event := new(Event)
     45 			if err := event.FromBucket(eb); err != nil {
     46 				return err
     47 			}
     48 			events = append(events, event)
     49 			return nil
     50 		})
     51 	})
     52 	if err != nil {
     53 		fmt.Println(err)
     54 	}
     55 	return events
     56 }
     57 
     58 // Delete event with the given ID.
     59 // Returns error if no such event can be found
     60 func Delete(idInt uint64) error {
     61 	db := database.GetDB()
     62 	id := database.Uint64ToBytes(idInt)
     63 	return db.Update(func(tx *bbolt.Tx) error {
     64 		b := tx.Bucket(database.BucketKeyEvents)
     65 		if b == nil {
     66 			log.Panic("The events bucket does not exist")
     67 		}
     68 		return b.DeleteBucket(id)
     69 	})
     70 }
     71 
     72 // Add persists a new event to database after generating an ID for it
     73 func Add(event *Event) error {
     74 	db := database.GetDB()
     75 	return db.Update(func(tx *bbolt.Tx) error {
     76 		b := tx.Bucket(database.BucketKeyEvents)
     77 		if b == nil {
     78 			log.Panic("The events bucket does not exist")
     79 		}
     80 
     81 		// Create a new event ID
     82 		idInt, err := b.NextSequence()
     83 		if err != nil {
     84 			return err
     85 		}
     86 		id := database.Uint64ToBytes(idInt)
     87 		event.ID = idInt
     88 
     89 		// Create the event bucket and fill it with data from event
     90 		eb, err := b.CreateBucket(id)
     91 		if err != nil {
     92 			return err
     93 		}
     94 		return event.toBucket(eb)
     95 	})
     96 }
     97 
     98 // Writes the event data to the given bucket
     99 func (event *Event) toBucket(eb *bbolt.Bucket) error {
    100 	var err error
    101 	id := database.Uint64ToBytes(event.ID)
    102 	serviceID := database.Uint64ToBytes(event.Service)
    103 	timestamp := database.Uint64ToBytes(event.Timestamp)
    104 	if err = eb.Put(keyEventID, id); err != nil {
    105 		return err
    106 	}
    107 	if eb.Put(keyEventService, serviceID); err != nil {
    108 		return err
    109 	}
    110 	if eb.Put(keyEventTimestamp, timestamp); err != nil {
    111 		return err
    112 	}
    113 	if eb.Put(keyEventStatus, []byte(event.Status)); err != nil {
    114 		return err
    115 	}
    116 	if eb.Put(keyEventTitle, []byte(event.Title)); err != nil {
    117 		return err
    118 	}
    119 	if eb.Put(keyEventDetails, []byte(event.Details)); err != nil {
    120 		return err
    121 	}
    122 	return nil
    123 }
    124 
    125 // Reads data from the given bucket into the fields of event
    126 // Returns error if any of the fields cannot be found
    127 func (event *Event) FromBucket(eb *bbolt.Bucket) error {
    128 	var id, service, timestamp []byte
    129 	var status, title, details []byte
    130 	err := errors.New("missing field from database")
    131 
    132 	// Get data from database
    133 	if id = eb.Get(keyEventID); id == nil {
    134 		return err
    135 	}
    136 	if service = eb.Get(keyEventService); service == nil {
    137 		return err
    138 	}
    139 	if timestamp = eb.Get(keyEventTimestamp); timestamp == nil {
    140 		return err
    141 	}
    142 	if status = eb.Get(keyEventStatus); status == nil {
    143 		return err
    144 	}
    145 	if title = eb.Get(keyEventTitle); title == nil {
    146 		return err
    147 	}
    148 	if details = eb.Get(keyEventDetails); details == nil {
    149 		return err
    150 	}
    151 
    152 	// Format data and set fields of event
    153 	event.ID = database.BytesToUint64(id)
    154 	event.Service = database.BytesToUint64(service)
    155 	event.Timestamp = database.BytesToUint64(timestamp)
    156 	event.Status = string(status)
    157 	event.Title = string(title)
    158 	event.Details = string(details)
    159 
    160 	return nil
    161 }