Logging Web Interface

**Work in progress**
This commit is contained in:
Thorsten 2015-02-26 16:37:36 +01:00
parent 45f2789048
commit 95b0dcb653
9 changed files with 130 additions and 11 deletions

View File

@ -33,6 +33,7 @@ func checkConfiguration() {
CheckSingleConfigurationPresentsAndAddIfMissing(`LogDBCacheSizeTime2FlushSeconds`, `6`) CheckSingleConfigurationPresentsAndAddIfMissing(`LogDBCacheSizeTime2FlushSeconds`, `6`)
CheckSingleConfigurationPresentsAndAddIfMissing(`LogDBEventsExpire`, `True`) CheckSingleConfigurationPresentsAndAddIfMissing(`LogDBEventsExpire`, `True`)
CheckSingleConfigurationPresentsAndAddIfMissing(`LogDBEventsExpireAfterDays`, `365`) CheckSingleConfigurationPresentsAndAddIfMissing(`LogDBEventsExpireAfterDays`, `365`)
CheckSingleConfigurationPresentsAndAddIfMissing(`LogDBWebInterfaceNameCacheRefreshTimeSeconds`, `500`)
CheckSingleConfigurationPresentsAndAddIfMissing(`LogBufferSize`, `500`) CheckSingleConfigurationPresentsAndAddIfMissing(`LogBufferSize`, `500`)
CheckSingleConfigurationPresentsAndAddIfMissing(`LogDeviceDelayNumberEvents`, `600`) CheckSingleConfigurationPresentsAndAddIfMissing(`LogDeviceDelayNumberEvents`, `600`)
CheckSingleConfigurationPresentsAndAddIfMissing(`LogDeviceDelayTime2FlushSeconds`, `5`) CheckSingleConfigurationPresentsAndAddIfMissing(`LogDeviceDelayTime2FlushSeconds`, `5`)

View File

@ -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)) 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) cache = make(chan LogDBEntry, cacheSizeNumberOfEvents)
initTimeout() initTimeout()
cacheRefreshSenderNames()
cacheRefreshMessageNames()
} }

View File

@ -6,7 +6,7 @@ import (
func ReadLatest() (events []LogDBEntry) { func ReadLatest() (events []LogDBEntry) {
query := logDBCollection.Find(bson.D{}).Sort(`TimeUTC`).Limit(26) query := logDBCollection.Find(bson.D{}).Sort(`-TimeUTC`).Limit(26)
count := 26 count := 26
if n, err := query.Count(); err == nil { if n, err := query.Count(); err == nil {

View File

@ -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
}

View File

@ -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
}

View File

@ -7,12 +7,17 @@ import (
) )
var ( var (
senderName LM.Sender = `System::Logger::Database` senderName LM.Sender = `System::Logger::Database`
mutexCacheFull sync.Mutex = sync.Mutex{} mutexCacheFull sync.Mutex = sync.Mutex{}
cache chan LogDBEntry = nil mutexCacheSenderNames sync.RWMutex = sync.RWMutex{}
cacheSizeNumberOfEvents int = 50 mutexCacheMessageNames sync.RWMutex = sync.RWMutex{}
cacheSizeTime2FlushSeconds int = 6 cache chan LogDBEntry = nil
logDB *mgo.Database = nil cacheSizeNumberOfEvents int = 50
logDBSession *mgo.Session = nil cacheSizeTime2FlushSeconds int = 6
logDBCollection *mgo.Collection = nil nameCachesRefreshTimeSeconds int = 300
cacheSenderNames []string = nil
cacheMessageNames []string = nil
logDB *mgo.Database = nil
logDBSession *mgo.Session = nil
logDBCollection *mgo.Collection = nil
) )

View File

@ -2,6 +2,7 @@ package Web
import ( import (
"github.com/SommerEngineering/Ocean/Log" "github.com/SommerEngineering/Ocean/Log"
"github.com/SommerEngineering/Ocean/Log/DeviceDatabase"
LM "github.com/SommerEngineering/Ocean/Log/Meta" LM "github.com/SommerEngineering/Ocean/Log/Meta"
"github.com/SommerEngineering/Ocean/Log/Web/Scheme" "github.com/SommerEngineering/Ocean/Log/Web/Scheme"
"github.com/SommerEngineering/Ocean/MimeTypes" "github.com/SommerEngineering/Ocean/MimeTypes"
@ -21,11 +22,14 @@ func HandlerWebLog(response http.ResponseWriter, request *http.Request) {
data := Scheme.Viewer{} data := Scheme.Viewer{}
data.Title = `Web Log Viewer` data.Title = `Web Log Viewer`
data.Sender = DeviceDatabase.ReadSenderNames()
data.MessageNames = DeviceDatabase.ReadMessageNames()
if countParameters < 9 { if countParameters < 9 {
// Initial view => refresh & first page (latest logs) // Initial view => refresh & first page (latest logs)
data.Events = readLatest() data.Events = readLatest()
} else { } else {
// Custom view // Custom view

View File

@ -1,8 +1,10 @@
package Web package Web
import ( import (
"fmt"
"github.com/SommerEngineering/Ocean/Log/DeviceDatabase" "github.com/SommerEngineering/Ocean/Log/DeviceDatabase"
"github.com/SommerEngineering/Ocean/Log/Web/Scheme" "github.com/SommerEngineering/Ocean/Log/Web/Scheme"
"strings"
) )
func readLatest() (events []Scheme.LogEvent) { func readLatest() (events []Scheme.LogEvent) {
@ -15,7 +17,7 @@ func readLatest() (events []Scheme.LogEvent) {
eventFromDB := eventsFromDB[n] eventFromDB := eventsFromDB[n]
events[n] = Scheme.LogEvent{} events[n] = Scheme.LogEvent{}
events[n].LogLine = eventFromDB.Format() 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 { if n%2 == 0 {
events[n].AB = Scheme.B events[n].AB = Scheme.B

View File

@ -15,6 +15,6 @@ type Viewer struct {
// </li> // </li>
type LogEvent struct { type LogEvent struct {
LogLine string 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 AB string // loga || logb
} }