WIP : Elektron Logging library #16

Merged
balandi1 merged 50 commits from master into master 2019-12-10 01:15:34 +00:00
12 changed files with 0 additions and 653 deletions
Showing only changes of commit cef6efee33 - Show all commits

View file

@ -1,29 +0,0 @@
// Copyright (C) 2018 spdfg
//
// This file is part of Elektron.
//
// Elektron is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Elektron is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Elektron. If not, see <http://www.gnu.org/licenses/>.
//
package logging
type ClsfnTaskDistOverheadLogger struct {
loggerObserverImpl
}
func (col ClsfnTaskDistOverheadLogger) Log(message string) {
// Logging the overhead of classifying tasks in the scheduling window and determining the distribution
// of light power consuming and heavy power consuming tasks.
col.logObserverSpecifics[clsfnTaskDistOverheadLogger].logFile.Println(message)
}

View file

@ -1,36 +0,0 @@
// Copyright (C) 2018 spdfg
//
// This file is part of Elektron.
//
// Elektron is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Elektron is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Elektron. If not, see <http://www.gnu.org/licenses/>.
//
package logging
import (
"log"
)
type ConsoleLogger struct {
loggerObserverImpl
}
func (cl ConsoleLogger) Log(message string) {
// We need to log to console only if the message is not empty
if message != "" {
log.Println(message)
// Also logging the message to the console log file
cl.logObserverSpecifics[conLogger].logFile.Println(message)
}
}

View file

@ -1,62 +0,0 @@
// Copyright (C) 2018 spdfg
//
// This file is part of Elektron.
//
// Elektron is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Elektron is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Elektron. If not, see <http://www.gnu.org/licenses/>.
//
package logging
import "github.com/fatih/color"
// Defining enums of log message types
var logMessageNames []string
// Possible log message types
var (
ERROR = messageNametoMessageType("ERROR")
WARNING = messageNametoMessageType("WARNING")
GENERAL = messageNametoMessageType("GENERAL")
SUCCESS = messageNametoMessageType("SUCCESS")
SCHED_TRACE = messageNametoMessageType("SCHED_TRACE")
PCP = messageNametoMessageType("PCP")
SPS = messageNametoMessageType("SPS")
CLSFN_TASKDIST_OVERHEAD = messageNametoMessageType("CLSFN_TASKDIST_OVERHEAD")
SCHED_WINDOW = messageNametoMessageType("SCHED_WINDOW")
)
// Text colors for the different types of log messages.
var LogMessageColors map[LogMessageType]*color.Color = map[LogMessageType]*color.Color{
ERROR: color.New(color.FgRed, color.Bold),
WARNING: color.New(color.FgYellow, color.Bold),
GENERAL: color.New(color.FgWhite, color.Bold),
SUCCESS: color.New(color.FgGreen, color.Bold),
}
type LogMessageType int
func (lmt LogMessageType) String() string {
return logMessageNames[lmt]
}
func GetLogMessageTypes() []string {
return logMessageNames
}
func messageNametoMessageType(messageName string) LogMessageType {
// Appending messageName to LogMessageNames
logMessageNames = append(logMessageNames, messageName)
// Mapping messageName to int
return LogMessageType(len(logMessageNames) - 1)
}

View file

@ -1,77 +0,0 @@
// Copyright (C) 2018 spdfg
//
// This file is part of Elektron.
//
// Elektron is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Elektron is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Elektron. If not, see <http://www.gnu.org/licenses/>.
//
package logging
import (
"time"
)
type LoggerDriver struct {
loggerSubject
allowedMessageTypes map[LogMessageType]bool
}
func newLogger() *LoggerDriver {
logger := &LoggerDriver{
allowedMessageTypes: map[LogMessageType]bool{
ERROR: true,
GENERAL: true,
WARNING: true,
SCHED_TRACE: true,
SUCCESS: true,
PCP: true,
SPS: true,
CLSFN_TASKDIST_OVERHEAD: true,
SCHED_WINDOW: true,
},
}
return logger
}
func BuildLogger(startTime time.Time, prefix string) *LoggerDriver {
// building logger
l := newLogger()
attachAllLoggers(l, startTime, prefix)
return l
}
func (log *LoggerDriver) EnabledLogging(messageType LogMessageType) {
log.allowedMessageTypes[messageType] = true
}
func (log *LoggerDriver) DisableLogging(messageType LogMessageType) {
log.allowedMessageTypes[messageType] = false
}
func (log *LoggerDriver) WriteLog(messageType LogMessageType, message string) {
// checking to see if logging for given messageType is disabled
if log.allowedMessageTypes[messageType] {
log.setMessage(message)
// notify registered loggers to log
log.notify(messageType)
}
}
func (log *LoggerDriver) Listen(logMType <-chan LogMessageType, logMsg <-chan string) {
for {
mType := <-logMType
msg := <-logMsg
log.WriteLog(mType, msg)
}
}

View file

@ -1,121 +0,0 @@
// Copyright (C) 2018 spdfg
//
// This file is part of Elektron.
//
// Elektron is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Elektron is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Elektron. If not, see <http://www.gnu.org/licenses/>.
//
package logging
import (
"strings"
"time"
logUtils "github.com/spdfg/elektron/logging/utils"
)
// Names of different loggers
const (
conLogger = "console-logger"
schedTraceLogger = "schedTrace-logger"
pcpLogger = "pcp-logger"
spsLogger = "schedPolicySwitch-logger"
clsfnTaskDistOverheadLogger = "classificationOverhead-logger"
schedWindowLogger = "schedWindow-logger"
)
// Logger class factory
var Loggers map[string]loggerObserver = map[string]loggerObserver{
conLogger: nil,
schedTraceLogger: nil,
pcpLogger: nil,
spsLogger: nil,
clsfnTaskDistOverheadLogger: nil,
schedWindowLogger: nil,
}
// Logger options to help initialize loggers
type loggerOption func(l loggerObserver) error
func withLogDirectory(startTime time.Time, prefix string) loggerOption {
return func(l loggerObserver) error {
l.(*loggerObserverImpl).setLogDirectory(logUtils.GetLogDir(startTime, prefix))
return nil
}
}
// This loggerOption initializes the specifics for each loggerObserver
func withLoggerSpecifics(prefix string) loggerOption {
return func(l loggerObserver) error {
l.(*loggerObserverImpl).logObserverSpecifics = map[string]*specifics{
conLogger: &specifics{},
schedTraceLogger: &specifics{},
pcpLogger: &specifics{},
spsLogger: &specifics{},
clsfnTaskDistOverheadLogger: &specifics{},
schedWindowLogger: &specifics{},
}
l.(*loggerObserverImpl).setLogFilePrefix(prefix)
l.(*loggerObserverImpl).setLogFile()
return nil
}
}
// Build and assign all loggers
func attachAllLoggers(lg *LoggerDriver, startTime time.Time, prefix string) {
loi := &loggerObserverImpl{}
loi.init(withLogDirectory(startTime, strings.Split(prefix, startTime.Format("20060102150405"))[0]),
withLoggerSpecifics(prefix))
Loggers[conLogger] = &ConsoleLogger{
loggerObserverImpl: *loi,
}
Loggers[schedTraceLogger] = &SchedTraceLogger{
loggerObserverImpl: *loi,
}
Loggers[pcpLogger] = &PCPLogger{
loggerObserverImpl: *loi,
}
Loggers[spsLogger] = &SchedPolicySwitchLogger{
loggerObserverImpl: *loi,
}
Loggers[clsfnTaskDistOverheadLogger] = &ClsfnTaskDistOverheadLogger{
loggerObserverImpl: *loi,
}
Loggers[schedWindowLogger] = &SchedWindowLogger{
loggerObserverImpl: *loi,
}
for _, lmt := range GetLogMessageTypes() {
switch lmt {
case SCHED_TRACE.String():
lg.attach(SCHED_TRACE, Loggers[schedTraceLogger])
case GENERAL.String():
lg.attach(GENERAL, Loggers[conLogger])
case WARNING.String():
lg.attach(WARNING, Loggers[conLogger])
case ERROR.String():
lg.attach(ERROR, Loggers[conLogger])
case SUCCESS.String():
lg.attach(SUCCESS, Loggers[conLogger])
case PCP.String():
lg.attach(PCP, Loggers[pcpLogger])
case SPS.String():
lg.attach(SPS, Loggers[spsLogger])
case CLSFN_TASKDIST_OVERHEAD.String():
lg.attach(CLSFN_TASKDIST_OVERHEAD, Loggers[clsfnTaskDistOverheadLogger])
case SCHED_WINDOW.String():
lg.attach(SCHED_WINDOW, Loggers[schedWindowLogger])
}
}
}

View file

@ -1,120 +0,0 @@
// Copyright (C) 2018 spdfg
//
// This file is part of Elektron.
//
// Elektron is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Elektron is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Elektron. If not, see <http://www.gnu.org/licenses/>.
//
package logging
import (
"fmt"
"log"
"os"
)
// Logging platform
type loggerObserver interface {
Log(message string)
setLogFile()
setLogFilePrefix(prefix string)
setLogDirectory(dirName string)
init(opts ...loggerOption)
}
type specifics struct {
logFilePrefix string
logFile *log.Logger
}
type loggerObserverImpl struct {
logFile *log.Logger
logObserverSpecifics map[string]*specifics
logDirectory string
}
func (loi *loggerObserverImpl) init(opts ...loggerOption) {
for _, opt := range opts {
// applying logger options
if err := opt(loi); err != nil {
log.Fatal(err)
}
}
}
func (loi loggerObserverImpl) Log(message string) {}
// Requires logFilePrefix to have already been set
func (loi *loggerObserverImpl) setLogFile() {
for prefix, ls := range loi.logObserverSpecifics {
if logFile, err := os.Create(ls.logFilePrefix); err != nil {
log.Fatal("Unable to create logFile: ", err)
} else {
fmt.Printf("Creating logFile with pathname: %s, and prefix: %s\n", ls.logFilePrefix, prefix)
ls.logFile = log.New(logFile, "", log.LstdFlags)
}
}
}
func (loi *loggerObserverImpl) setLogFilePrefix(prefix string) {
// Setting logFilePrefix for pcp logger
pcpLogFilePrefix := prefix + ".pcplog"
if loi.logDirectory != "" {
pcpLogFilePrefix = loi.logDirectory + "/" + pcpLogFilePrefix
}
loi.logObserverSpecifics[pcpLogger].logFilePrefix = pcpLogFilePrefix
// Setting logFilePrefix for console logger
consoleLogFilePrefix := prefix + "_console.log"
if loi.logDirectory != "" {
consoleLogFilePrefix = loi.logDirectory + "/" + consoleLogFilePrefix
}
loi.logObserverSpecifics[conLogger].logFilePrefix = consoleLogFilePrefix
// Setting logFilePrefix for schedTrace logger
schedTraceLogFilePrefix := prefix + "_schedTrace.log"
if loi.logDirectory != "" {
schedTraceLogFilePrefix = loi.logDirectory + "/" + schedTraceLogFilePrefix
}
loi.logObserverSpecifics[schedTraceLogger].logFilePrefix = schedTraceLogFilePrefix
// Setting logFilePrefix for schedulingPolicySwitch logger
schedPolicySwitchLogFilePrefix := prefix + "_schedPolicySwitch.log"
if loi.logDirectory != "" {
schedPolicySwitchLogFilePrefix = loi.logDirectory + "/" + schedPolicySwitchLogFilePrefix
}
loi.logObserverSpecifics[spsLogger].logFilePrefix = schedPolicySwitchLogFilePrefix
// Setting logFilePrefix for clsfnTaskDist logger.
// Execution time of every call to def.GetTaskDistribution(...) would be recorded and logged in this file.
// The overhead would be logged in microseconds.
clsfnTaskDistOverheadLogFilePrefix := prefix + "_classificationOverhead.log"
if loi.logDirectory != "" {
clsfnTaskDistOverheadLogFilePrefix = loi.logDirectory + "/" + clsfnTaskDistOverheadLogFilePrefix
}
loi.logObserverSpecifics[clsfnTaskDistOverheadLogger].logFilePrefix = clsfnTaskDistOverheadLogFilePrefix
// Setting logFilePrefix for schedWindow logger.
// Going to log the time stamp when the scheduling window was determined
// and the size of the scheduling window.
schedWindowLogFilePrefix := prefix + "_schedWindow.log"
if loi.logDirectory != "" {
schedWindowLogFilePrefix = loi.logDirectory + "/" + schedWindowLogFilePrefix
}
loi.logObserverSpecifics[schedWindowLogger].logFilePrefix = schedWindowLogFilePrefix
}
func (loi *loggerObserverImpl) setLogDirectory(dirName string) {
loi.logDirectory = dirName
}

View file

@ -1,41 +0,0 @@
// Copyright (C) 2018 spdfg
//
// This file is part of Elektron.
//
// Elektron is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Elektron is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Elektron. If not, see <http://www.gnu.org/licenses/>.
//
package logging
type loggerSubject struct {
Registry map[LogMessageType][]loggerObserver
message string
}
func (ls *loggerSubject) setMessage(message string) {
ls.message = message
}
func (ls *loggerSubject) attach(messageType LogMessageType, lo loggerObserver) {
if ls.Registry == nil {
ls.Registry = make(map[LogMessageType][]loggerObserver)
}
ls.Registry[messageType] = append(ls.Registry[messageType], lo)
}
func (ls *loggerSubject) notify(messageType LogMessageType) {
for _, logObserver := range ls.Registry[messageType] {
logObserver.Log(ls.message)
}
}

View file

@ -1,27 +0,0 @@
// Copyright (C) 2018 spdfg
//
// This file is part of Elektron.
//
// Elektron is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Elektron is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Elektron. If not, see <http://www.gnu.org/licenses/>.
//
package logging
type PCPLogger struct {
loggerObserverImpl
}
func (pl *PCPLogger) Log(message string) {
pl.logObserverSpecifics[pcpLogger].logFile.Println(message)
}

View file

@ -1,27 +0,0 @@
// Copyright (C) 2018 spdfg
//
// This file is part of Elektron.
//
// Elektron is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Elektron is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Elektron. If not, see <http://www.gnu.org/licenses/>.
//
package logging
type SchedPolicySwitchLogger struct {
loggerObserverImpl
}
func (pl *SchedPolicySwitchLogger) Log(message string) {
pl.logObserverSpecifics[spsLogger].logFile.Println(message)
}

View file

@ -1,28 +0,0 @@
// Copyright (C) 2018 spdfg
//
// This file is part of Elektron.
//
// Elektron is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Elektron is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Elektron. If not, see <http://www.gnu.org/licenses/>.
//
package logging
type SchedTraceLogger struct {
loggerObserverImpl
}
func (stl SchedTraceLogger) Log(message string) {
// Logging schedule trace to mentioned file
stl.logObserverSpecifics[schedTraceLogger].logFile.Println(message)
}

View file

@ -1,28 +0,0 @@
// Copyright (C) 2018 spdfg
//
// This file is part of Elektron.
//
// Elektron is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Elektron is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Elektron. If not, see <http://www.gnu.org/licenses/>.
//
package logging
type SchedWindowLogger struct {
loggerObserverImpl
}
func (swl SchedWindowLogger) Log(message string) {
// Logging schedule trace to mentioned file
swl.logObserverSpecifics[schedWindowLogger].logFile.Println(message)
}

View file

@ -1,57 +0,0 @@
// Copyright (C) 2018 spdfg
//
// This file is part of Elektron.
//
// Elektron is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Elektron is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Elektron. If not, see <http://www.gnu.org/licenses/>.
//
package logging
import (
"log"
"os"
"strconv"
"time"
)
var LogDir string
func GetLogDir(startTime time.Time, prefix string) string {
if LogDir == "" {
LogDir = createLogDir(prefix, startTime)
}
return LogDir
}
func createLogDir(prefix string, startTime time.Time) string {
// Creating directory to store all logs for this run
logDirName := "./" + prefix + strconv.Itoa(startTime.Year())
logDirName += "-"
logDirName += startTime.Month().String()
logDirName += "-"
logDirName += strconv.Itoa(startTime.Day())
logDirName += "_"
logDirName += strconv.Itoa(startTime.Hour())
logDirName += "-"
logDirName += strconv.Itoa(startTime.Minute())
logDirName += "-"
logDirName += strconv.Itoa(startTime.Second())
if _, err := os.Stat(logDirName); os.IsNotExist(err) {
os.Mkdir(logDirName, 0755)
} else {
log.Println("Unable to create log directory: ", err)
logDirName = ""
}
return logDirName
}