diff --git a/ConfigurationDB/CheckConfiguration.go b/ConfigurationDB/CheckConfiguration.go index 9fd36c7..55d6c2b 100644 --- a/ConfigurationDB/CheckConfiguration.go +++ b/ConfigurationDB/CheckConfiguration.go @@ -33,6 +33,7 @@ func checkConfiguration() { CheckSingleConfigurationPresentsAndAddIfMissing(`LogDBCacheSizeTime2FlushSeconds`, `6`) CheckSingleConfigurationPresentsAndAddIfMissing(`LogDBEventsExpire`, `True`) CheckSingleConfigurationPresentsAndAddIfMissing(`LogDBEventsExpireAfterDays`, `365`) + CheckSingleConfigurationPresentsAndAddIfMissing(`LogDBWebInterfaceNameCacheRefreshTimeSeconds`, `500`) CheckSingleConfigurationPresentsAndAddIfMissing(`LogBufferSize`, `500`) CheckSingleConfigurationPresentsAndAddIfMissing(`LogDeviceDelayNumberEvents`, `600`) CheckSingleConfigurationPresentsAndAddIfMissing(`LogDeviceDelayTime2FlushSeconds`, `5`) diff --git a/Log/DeviceDatabase/Init.go b/Log/DeviceDatabase/Init.go index f9ed9a0..c355e39 100644 --- a/Log/DeviceDatabase/Init.go +++ b/Log/DeviceDatabase/Init.go @@ -28,6 +28,15 @@ func init() { Log.LogShort(senderName, LM.CategorySYSTEM, LM.LevelINFO, LM.MessageNameCONFIGURATION, `Configuration LogDBCacheSizeTime2FlushSeconds was loaded.`, fmt.Sprintf(`The value is %d.`, cacheSizeTime2FlushSeconds)) } + if value, err := strconv.Atoi(ConfigurationDB.Read(`LogDBWebInterfaceNameCacheRefreshTimeSeconds`)); err != nil { + Log.LogFull(senderName, LM.CategorySYSTEM, LM.LevelERROR, LM.SeverityHigh, LM.ImpactUnknown, LM.MessageNameCONFIGURATION, `It was not possible to read the LogDBWebInterfaceNameCacheRefreshTimeSeconds configuration.`, `The default value will be used.`, fmt.Sprintf(`Default value is %d.`, nameCachesRefreshTimeSeconds)) + } else { + nameCachesRefreshTimeSeconds = value + Log.LogShort(senderName, LM.CategorySYSTEM, LM.LevelINFO, LM.MessageNameCONFIGURATION, `Configuration LogDBWebInterfaceNameCacheRefreshTimeSeconds was loaded.`, fmt.Sprintf(`The value is %d.`, nameCachesRefreshTimeSeconds)) + } + cache = make(chan LogDBEntry, cacheSizeNumberOfEvents) initTimeout() + cacheRefreshSenderNames() + cacheRefreshMessageNames() } diff --git a/Log/DeviceDatabase/ReadLatest.go b/Log/DeviceDatabase/ReadLatest.go index c9c07f5..9a8054e 100644 --- a/Log/DeviceDatabase/ReadLatest.go +++ b/Log/DeviceDatabase/ReadLatest.go @@ -6,7 +6,7 @@ import ( func ReadLatest() (events []LogDBEntry) { - query := logDBCollection.Find(bson.D{}).Sort(`TimeUTC`).Limit(26) + query := logDBCollection.Find(bson.D{}).Sort(`-TimeUTC`).Limit(26) count := 26 if n, err := query.Count(); err == nil { diff --git a/Log/DeviceDatabase/ReadMessageNames.go b/Log/DeviceDatabase/ReadMessageNames.go new file mode 100644 index 0000000..1b12b32 --- /dev/null +++ b/Log/DeviceDatabase/ReadMessageNames.go @@ -0,0 +1,49 @@ +package DeviceDatabase + +import ( + "github.com/SommerEngineering/Ocean/Log" + LM "github.com/SommerEngineering/Ocean/Log/Meta" + "github.com/SommerEngineering/Ocean/Shutdown" + "gopkg.in/mgo.v2/bson" + "sort" + "time" +) + +func ReadMessageNames() (messageNames []string) { + mutexCacheMessageNames.RLock() + defer mutexCacheMessageNames.RUnlock() + messageNames = cacheMessageNames + return +} + +func cacheRefreshMessageNames() { + Log.LogShort(senderName, LM.CategorySYSTEM, LM.LevelINFO, LM.MessageNameSTARTUP, `The message names' refresh thread is now running.`) + go func() { + for true { + mutexCacheMessageNames.Lock() + cacheMessageNames = readMessageNamesFromDB() + mutexCacheMessageNames.Unlock() + + Log.LogShort(senderName, LM.CategorySYSTEM, LM.LevelTALKATIVE, LM.MessageNameEXECUTE, `The message names' cache was refreshed.`) + time.Sleep(time.Duration(nameCachesRefreshTimeSeconds) * time.Second) + + if Shutdown.IsDown() { + Log.LogFull(senderName, LM.CategorySYSTEM, LM.LevelWARN, LM.SeverityLow, LM.ImpactLow, LM.MessageNameSHUTDOWN, `The message name's refresh thread is now shutting down.`) + return + } + } + }() +} + +func readMessageNamesFromDB() (result []string) { + + var nextMessageNames []string + if err := logDBCollection.Find(bson.D{}).Distinct(`MessageName`, &nextMessageNames); err != nil { + Log.LogShort(senderName, LM.CategorySYSTEM, LM.LevelERROR, LM.MessageNameDATABASE, `Was not able to read the message names from the database.`, err.Error()) + return + } + + sort.Strings(nextMessageNames) + result = nextMessageNames + return +} diff --git a/Log/DeviceDatabase/ReadSenderNames.go b/Log/DeviceDatabase/ReadSenderNames.go new file mode 100644 index 0000000..865abf1 --- /dev/null +++ b/Log/DeviceDatabase/ReadSenderNames.go @@ -0,0 +1,49 @@ +package DeviceDatabase + +import ( + "github.com/SommerEngineering/Ocean/Log" + LM "github.com/SommerEngineering/Ocean/Log/Meta" + "github.com/SommerEngineering/Ocean/Shutdown" + "gopkg.in/mgo.v2/bson" + "sort" + "time" +) + +func ReadSenderNames() (senderNames []string) { + mutexCacheSenderNames.RLock() + defer mutexCacheSenderNames.RUnlock() + senderNames = cacheSenderNames + return +} + +func cacheRefreshSenderNames() { + Log.LogShort(senderName, LM.CategorySYSTEM, LM.LevelINFO, LM.MessageNameSTARTUP, `The sender names' refresh thread is now running.`) + go func() { + for true { + mutexCacheSenderNames.Lock() + cacheSenderNames = readSenderNamesFromDB() + mutexCacheSenderNames.Unlock() + + Log.LogShort(senderName, LM.CategorySYSTEM, LM.LevelTALKATIVE, LM.MessageNameEXECUTE, `The sender names' cache was refreshed.`) + time.Sleep(time.Duration(nameCachesRefreshTimeSeconds) * time.Second) + + if Shutdown.IsDown() { + Log.LogFull(senderName, LM.CategorySYSTEM, LM.LevelWARN, LM.SeverityLow, LM.ImpactLow, LM.MessageNameSHUTDOWN, `The sender name's refresh thread is now shutting down.`) + return + } + } + }() +} + +func readSenderNamesFromDB() (result []string) { + + var nextSenderNames []string + if err := logDBCollection.Find(bson.D{}).Distinct(`Sender`, &nextSenderNames); err != nil { + Log.LogShort(senderName, LM.CategorySYSTEM, LM.LevelERROR, LM.MessageNameDATABASE, `Was not able to read the sender names from the database.`, err.Error()) + return + } + + sort.Strings(nextSenderNames) + result = nextSenderNames + return +} diff --git a/Log/DeviceDatabase/Variables.go b/Log/DeviceDatabase/Variables.go index 02eda6a..8579c4b 100644 --- a/Log/DeviceDatabase/Variables.go +++ b/Log/DeviceDatabase/Variables.go @@ -7,12 +7,17 @@ import ( ) var ( - senderName LM.Sender = `System::Logger::Database` - mutexCacheFull sync.Mutex = sync.Mutex{} - cache chan LogDBEntry = nil - cacheSizeNumberOfEvents int = 50 - cacheSizeTime2FlushSeconds int = 6 - logDB *mgo.Database = nil - logDBSession *mgo.Session = nil - logDBCollection *mgo.Collection = nil + senderName LM.Sender = `System::Logger::Database` + mutexCacheFull sync.Mutex = sync.Mutex{} + mutexCacheSenderNames sync.RWMutex = sync.RWMutex{} + mutexCacheMessageNames sync.RWMutex = sync.RWMutex{} + cache chan LogDBEntry = nil + cacheSizeNumberOfEvents int = 50 + cacheSizeTime2FlushSeconds int = 6 + nameCachesRefreshTimeSeconds int = 300 + cacheSenderNames []string = nil + cacheMessageNames []string = nil + logDB *mgo.Database = nil + logDBSession *mgo.Session = nil + logDBCollection *mgo.Collection = nil ) diff --git a/Log/Web/HandlerLog.go b/Log/Web/HandlerLog.go index 8b9374f..295d1de 100644 --- a/Log/Web/HandlerLog.go +++ b/Log/Web/HandlerLog.go @@ -2,6 +2,7 @@ package Web import ( "github.com/SommerEngineering/Ocean/Log" + "github.com/SommerEngineering/Ocean/Log/DeviceDatabase" LM "github.com/SommerEngineering/Ocean/Log/Meta" "github.com/SommerEngineering/Ocean/Log/Web/Scheme" "github.com/SommerEngineering/Ocean/MimeTypes" @@ -21,11 +22,14 @@ func HandlerWebLog(response http.ResponseWriter, request *http.Request) { data := Scheme.Viewer{} data.Title = `Web Log Viewer` + data.Sender = DeviceDatabase.ReadSenderNames() + data.MessageNames = DeviceDatabase.ReadMessageNames() if countParameters < 9 { // Initial view => refresh & first page (latest logs) data.Events = readLatest() + } else { // Custom view diff --git a/Log/Web/ReadLatest.go b/Log/Web/ReadLatest.go index ba86442..c1e5421 100644 --- a/Log/Web/ReadLatest.go +++ b/Log/Web/ReadLatest.go @@ -1,8 +1,10 @@ package Web import ( + "fmt" "github.com/SommerEngineering/Ocean/Log/DeviceDatabase" "github.com/SommerEngineering/Ocean/Log/Web/Scheme" + "strings" ) func readLatest() (events []Scheme.LogEvent) { @@ -15,7 +17,7 @@ func readLatest() (events []Scheme.LogEvent) { eventFromDB := eventsFromDB[n] events[n] = Scheme.LogEvent{} events[n].LogLine = eventFromDB.Format() - events[n].LogLevel = eventFromDB.Level // TODO => Change also the template (Webflow, CSS classes) + events[n].LogLevel = fmt.Sprintf("log%s", strings.ToLower(eventFromDB.Level[2:])) if n%2 == 0 { events[n].AB = Scheme.B diff --git a/Log/Web/Scheme/Scheme.go b/Log/Web/Scheme/Scheme.go index 8304801..cbe6305 100644 --- a/Log/Web/Scheme/Scheme.go +++ b/Log/Web/Scheme/Scheme.go @@ -15,6 +15,6 @@ type Viewer struct { // type LogEvent struct { LogLine string - LogLevel string // L:DEBUG || L:ERROR || L:INFO || L:SECURITY || L:TALKATIVE || L:WARN + LogLevel string // logwarn || logdebug || logerror || loginfo || logtalkative || logsecurity AB string // loga || logb }