Elektron Logging library (#16)

switch to logrus for logging.

replaced old logging library with a wrapper around logrus.
We now just need to use the exported Log(...) and Logf(...) from the logging/
package that wraps around a set of loggers constituting a chain (following COR).
Loggers are configured using a YAML file that specifies the following.
1. enabled/disabled
2. whether the message should be logged on console.
3. filename extension.
4. minimum log level.

Retrofitted source code to now use the updated logging library.
Updated the documentation with information regarding the specification
of the log config file.

Currently, the log format in the config file is not adhered to. This is going to be
addressed in a future commit.
This commit is contained in:
Bhargavi Hanumant Alandikar 2019-12-09 20:15:33 -05:00 committed by PRADYUMNA KAUSHIK
parent 9977251c14
commit 3543960689
61 changed files with 1510 additions and 1067 deletions

View file

@ -0,0 +1,117 @@
// 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 (
"os"
"path/filepath"
"strings"
log "github.com/sirupsen/logrus"
)
type clsfnTaskDistrOverheadLogger struct {
baseElektronLogger
}
func newClsfnTaskDistrOverheadLogger(
config *loggerConfig,
b *baseLogData,
logType int,
prefix string,
logger *log.Logger,
logDir *logDirectory) *clsfnTaskDistrOverheadLogger {
cLog := &clsfnTaskDistrOverheadLogger{
baseElektronLogger: baseElektronLogger{
baseLogData: b,
config: struct {
Enabled bool
FilenameExtension string
AllowOnConsole bool
}{
Enabled: config.TaskDistrConfig.Enabled,
FilenameExtension: config.TaskDistrConfig.FilenameExtension,
AllowOnConsole: config.TaskDistrConfig.AllowOnConsole,
},
logType: logType,
next: nil,
logger: logger,
logDir: logDir,
},
}
cLog.createLogFile(prefix)
return cLog
}
func (cLog clsfnTaskDistrOverheadLogger) Log(logType int, level log.Level, message string) {
if cLog.logType == logType {
if cLog.isEnabled() {
if cLog.isAllowedOnConsole() {
cLog.logger.SetOutput(os.Stdout)
cLog.logger.WithFields(cLog.data).Log(level, message)
}
cLog.logger.SetOutput(cLog.logFile)
cLog.logger.WithFields(cLog.data).Log(level, message)
}
}
// Forwarding to next logger
if cLog.next != nil {
cLog.next.Log(logType, level, message)
} else {
// Clearing the fields.
cLog.resetFields()
}
}
func (cLog clsfnTaskDistrOverheadLogger) Logf(logType int, level log.Level, msgFmtString string, args ...interface{}) {
if cLog.logType == logType {
if cLog.isEnabled() {
if cLog.isAllowedOnConsole() {
cLog.logger.SetOutput(os.Stdout)
cLog.logger.WithFields(cLog.data).Logf(level, msgFmtString, args...)
}
cLog.logger.SetOutput(cLog.logFile)
cLog.logger.WithFields(cLog.data).Logf(level, msgFmtString, args...)
}
}
if cLog.next != nil {
cLog.next.Logf(logType, level, msgFmtString, args...)
} else {
// Clearing the fields.
cLog.resetFields()
}
}
func (cLog *clsfnTaskDistrOverheadLogger) createLogFile(prefix string) {
if cLog.isEnabled() {
filename := strings.Join([]string{prefix, cLog.getFilenameExtension()}, "")
dirName := cLog.logDir.getDirName()
if dirName != "" {
if logFile, err := os.Create(filepath.Join(dirName, filename)); err != nil {
log.Fatal("Unable to create logFile: ", err)
} else {
cLog.logFile = logFile
}
}
}
}

117
logging/consoleLogger.go Normal file
View file

@ -0,0 +1,117 @@
// 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 (
"os"
"path/filepath"
"strings"
log "github.com/sirupsen/logrus"
)
type consoleLogger struct {
baseElektronLogger
MinLogLevel string
}
func newConsoleLogger(
config *loggerConfig,
b *baseLogData,
logType int,
prefix string,
logger *log.Logger,
logDir *logDirectory) *consoleLogger {
cLog := &consoleLogger{
baseElektronLogger: baseElektronLogger{
baseLogData: b,
config: struct {
Enabled bool
FilenameExtension string
AllowOnConsole bool
}{
Enabled: config.ConsoleConfig.Enabled,
FilenameExtension: config.ConsoleConfig.FilenameExtension,
AllowOnConsole: config.ConsoleConfig.AllowOnConsole,
},
logType: logType,
next: nil,
logger: logger,
logDir: logDir,
},
MinLogLevel: config.ConsoleConfig.MinLogLevel,
}
cLog.createLogFile(prefix)
return cLog
}
func (cLog consoleLogger) Log(logType int, level log.Level, message string) {
if logType <= cLog.logType {
if cLog.isEnabled() {
cLog.logger.SetOutput(os.Stdout)
cLog.logger.WithFields(cLog.data).Log(level, message)
cLog.logger.SetOutput(cLog.logFile)
cLog.logger.WithFields(cLog.data).Log(level, message)
}
}
// Forwarding to next logger.
if cLog.next != nil {
cLog.next.Log(logType, level, message)
} else {
// Clearing the fields.
cLog.resetFields()
}
}
func (cLog consoleLogger) Logf(logType int, level log.Level, msgFmtString string, args ...interface{}) {
if logType <= cLog.logType {
if cLog.isEnabled() {
cLog.logger.SetOutput(os.Stdout)
cLog.logger.WithFields(cLog.data).Logf(level, msgFmtString, args...)
cLog.logger.SetOutput(cLog.logFile)
cLog.logger.WithFields(cLog.data).Logf(level, msgFmtString, args...)
}
}
if cLog.next != nil {
cLog.next.Logf(logType, level, msgFmtString, args...)
} else {
// Clearing the fields.
cLog.resetFields()
}
}
func (cLog *consoleLogger) createLogFile(prefix string) {
// Create log file for the type if it is enabled.
if cLog.isEnabled() {
filename := strings.Join([]string{prefix, cLog.getFilenameExtension()}, "")
dirName := cLog.logDir.getDirName()
if dirName != "" {
if logFile, err := os.Create(filepath.Join(dirName, filename)); err != nil {
log.Fatal("Unable to create logFile: ", err)
} else {
cLog.logFile = logFile
}
}
}
}

57
logging/createLogDir.go Normal file
View file

@ -0,0 +1,57 @@
// 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 (
"os"
"strconv"
"strings"
"time"
log "github.com/sirupsen/logrus"
)
type logDirectory struct {
name string
}
func (logD *logDirectory) getDirName() string {
return logD.name
}
func (logD *logDirectory) createLogDir(prefix string, startTime time.Time) {
if logD.name == "" {
// Creating directory to store all logs for this run. Directory name format : _2019-November-21_14-33-0.
prefix = prefix + "_"
logDirName := strings.Join([]string{"./", prefix, strconv.Itoa(startTime.Year())}, "")
logDirName = strings.Join([]string{logDirName, startTime.Month().String(), strconv.Itoa(startTime.Day())}, "-")
logDirName = strings.Join([]string{logDirName, strconv.Itoa(startTime.Hour())}, "_")
logDirName = strings.Join([]string{logDirName, strconv.Itoa(startTime.Minute()), 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 = ""
}
logD.name = logDirName
}
}

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

@ -0,0 +1,54 @@
// 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 (
"bytes"
"fmt"
"strings"
log "github.com/sirupsen/logrus"
)
type elektronFormatter struct {
TimestampFormat string
}
func (f elektronFormatter) Format(entry *log.Entry) ([]byte, error) {
var b *bytes.Buffer
if entry.Buffer != nil {
b = entry.Buffer
} else {
b = &bytes.Buffer{}
}
level := fmt.Sprintf("[%s]:", strings.ToUpper(entry.Level.String()))
message := strings.Join([]string{level, entry.Time.Format(f.TimestampFormat), entry.Message, " "}, " ")
var formattedFields []string
for key, value := range entry.Data {
formattedFields = append(formattedFields, strings.Join([]string{key, value.(string)}, "="))
}
b.WriteString(message)
b.WriteString(strings.Join(formattedFields, ", "))
b.WriteByte('\n')
return b.Bytes(), nil
}

165
logging/logger.go Normal file
View file

@ -0,0 +1,165 @@
// 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/pkg/errors"
"os"
"strings"
"time"
log "github.com/sirupsen/logrus"
. "github.com/spdfg/elektron/logging/types"
)
// var config loggerConfig
var formatter elektronFormatter
var elektronLoggerInstance elektronLogger
type elektronLogger interface {
setNext(next elektronLogger)
Log(logType int, level log.Level, message string)
Logf(logType int, level log.Level, msgFmtString string, args ...interface{})
WithFields(logData log.Fields) elektronLogger
WithField(key string, value string) elektronLogger
}
type baseLogData struct {
data log.Fields
}
type baseElektronLogger struct {
*baseLogData
config struct {
Enabled bool
FilenameExtension string
AllowOnConsole bool
}
logType int
logFile *os.File
next elektronLogger
logger *log.Logger
logDir *logDirectory
}
func (l baseElektronLogger) isEnabled() bool {
return l.config.Enabled
}
func (l baseElektronLogger) isAllowedOnConsole() bool {
return l.config.AllowOnConsole
}
func (l baseElektronLogger) getFilenameExtension() string {
return l.config.FilenameExtension
}
func (l *baseElektronLogger) WithFields(logData log.Fields) elektronLogger {
l.data = logData
return l
}
func (l *baseElektronLogger) WithField(key string, value string) elektronLogger {
l.data[key] = value
return l
}
func (l *baseElektronLogger) setNext(next elektronLogger) {
l.next = next
}
func (l baseElektronLogger) Log(logType int, level log.Level, message string) {
if l.next != nil {
l.next.Log(logType, level, message)
}
}
func (l baseElektronLogger) Logf(logType int, level log.Level, msgFmtString string, args ...interface{}) {
if l.next != nil {
l.next.Logf(logType, level, msgFmtString, args...)
}
}
func (l *baseElektronLogger) resetFields() {
l.data = nil
l.data = log.Fields{}
}
func BuildLogger(prefix string, logConfigFilename string) error {
// Create the log directory.
startTime := time.Now()
formatter.TimestampFormat = "2006-01-02 15:04:05"
formattedStartTime := startTime.Format("20060102150405")
logDir := &logDirectory{}
logDir.createLogDir(prefix, startTime)
// Instantiate the logrus instance.
prefix = strings.Join([]string{prefix, formattedStartTime}, "_")
logger := &log.Logger{
Out: os.Stderr,
Level: log.DebugLevel,
Formatter: &formatter,
}
// Create a chain of loggers.
b := &baseLogData{data: log.Fields{}}
head := &baseElektronLogger{baseLogData: b}
// Read configuration from yaml.
if config, err := getConfig(logConfigFilename); err != nil {
return errors.Wrap(err, "Failed to build logger")
} else {
cLog := newConsoleLogger(config, b, CONSOLE, prefix, logger, logDir)
pLog := newPCPLogger(config, b, PCP, prefix, logger, logDir)
schedTraceLog := newSchedTraceLogger(config, b, SCHED_TRACE, prefix, logger, logDir)
spsLog := newSchedPolicySwitchLogger(config, b, SPS, prefix, logger, logDir)
schedWindowLog := newSchedWindowLogger(config, b, SCHED_WINDOW, prefix, logger, logDir)
tskDistLog := newClsfnTaskDistrOverheadLogger(config, b, CLSFN_TASKDISTR_OVERHEAD, prefix, logger, logDir)
head.setNext(cLog)
cLog.setNext(pLog)
pLog.setNext(schedTraceLog)
schedTraceLog.setNext(spsLog)
spsLog.setNext(schedWindowLog)
schedWindowLog.setNext(tskDistLog)
}
elektronLoggerInstance = head
return nil
}
func Log(logType int, level log.Level, message string) {
elektronLoggerInstance.Log(logType, level, message)
}
func Logf(logType int, level log.Level, msgFmtString string, args ...interface{}) {
elektronLoggerInstance.Logf(logType, level, msgFmtString, args...)
}
func WithFields(logData log.Fields) elektronLogger {
return elektronLoggerInstance.WithFields(logData)
}
func WithField(key string, value string) elektronLogger {
return elektronLoggerInstance.WithField(key, value)
}

83
logging/loggerConfig.go Normal file
View file

@ -0,0 +1,83 @@
// 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/pkg/errors"
log "github.com/sirupsen/logrus"
"gopkg.in/yaml.v2"
"io/ioutil"
)
type loggerConfig struct {
SchedTraceConfig struct {
Enabled bool `yaml:"enabled"`
FilenameExtension string `yaml:"filenameExtension"`
AllowOnConsole bool `yaml:"allowOnConsole"`
} `yaml:"schedTrace"`
PCPConfig struct {
Enabled bool `yaml:"enabled"`
FilenameExtension string `yaml:"filenameExtension"`
AllowOnConsole bool `yaml:"allowOnConsole"`
} `yaml:"pcp"`
ConsoleConfig struct {
Enabled bool `yaml:"enabled"`
FilenameExtension string `yaml:"filenameExtension"`
MinLogLevel string `yaml:"minLogLevel"`
AllowOnConsole bool `yaml:"allowOnConsole"`
} `yaml:"console"`
SPSConfig struct {
Enabled bool `yaml:"enabled"`
FilenameExtension string `yaml:"filenameExtension"`
AllowOnConsole bool `yaml:"allowOnConsole"`
} `yaml:"sps"`
TaskDistrConfig struct {
Enabled bool `yaml:"enabled"`
FilenameExtension string `yaml:"filenameExtension"`
AllowOnConsole bool `yaml:"allowOnConsole"`
} `yaml:"clsfnTaskDistrOverhead"`
SchedWindowConfig struct {
Enabled bool `yaml:"enabled"`
FilenameExtension string `yaml:"filenameExtension"`
AllowOnConsole bool `yaml:"allowOnConsole"`
} `yaml:"schedWindow"`
Format []string `yaml:"format"`
}
func getConfig(logConfigFilename string) (*loggerConfig, error) {
yamlFile, err := ioutil.ReadFile(logConfigFilename)
if err != nil {
return nil, errors.Wrap(err, "failed to read log config file")
}
c := &loggerConfig{}
err = yaml.Unmarshal(yamlFile, c)
if err != nil {
log.Fatalf("Error in unmarshalling yaml: %v", err)
}
return c, nil
}

117
logging/pcpLogger.go Normal file
View file

@ -0,0 +1,117 @@
// 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 (
"os"
"path/filepath"
"strings"
log "github.com/sirupsen/logrus"
)
type pcpLogger struct {
baseElektronLogger
}
func newPCPLogger(
config *loggerConfig,
b *baseLogData,
logType int,
prefix string,
logger *log.Logger,
logDir *logDirectory) *pcpLogger {
pLog := &pcpLogger{
baseElektronLogger: baseElektronLogger{
baseLogData: b,
config: struct {
Enabled bool
FilenameExtension string
AllowOnConsole bool
}{
Enabled: config.PCPConfig.Enabled,
FilenameExtension: config.PCPConfig.FilenameExtension,
AllowOnConsole: config.PCPConfig.AllowOnConsole,
},
logType: logType,
next: nil,
logger: logger,
logDir: logDir,
},
}
pLog.createLogFile(prefix)
return pLog
}
func (pLog pcpLogger) Log(logType int, level log.Level, message string) {
if pLog.logType == logType {
if pLog.isEnabled() {
if pLog.isAllowedOnConsole() {
pLog.logger.SetOutput(os.Stdout)
pLog.logger.WithFields(pLog.data).Log(level, message)
}
pLog.logger.SetOutput(pLog.logFile)
pLog.logger.WithFields(pLog.data).Log(level, message)
}
}
if pLog.next != nil {
pLog.next.Log(logType, level, message)
} else {
// Clearing the fields.
pLog.resetFields()
}
}
func (pLog pcpLogger) Logf(logType int, level log.Level, msgFmtString string, args ...interface{}) {
if pLog.logType == logType {
if pLog.isEnabled() {
if pLog.isAllowedOnConsole() {
pLog.logger.SetOutput(os.Stdout)
pLog.logger.WithFields(pLog.data).Logf(level, msgFmtString, args...)
}
pLog.logger.SetOutput(pLog.logFile)
pLog.logger.WithFields(pLog.data).Logf(level, msgFmtString, args...)
}
}
// Forwarding to next logger
if pLog.next != nil {
pLog.next.Logf(logType, level, msgFmtString, args...)
} else {
// Clearing the fields.
pLog.resetFields()
}
}
func (pLog *pcpLogger) createLogFile(prefix string) {
if pLog.isEnabled() {
filename := strings.Join([]string{prefix, pLog.getFilenameExtension()}, "")
dirName := pLog.logDir.getDirName()
if dirName != "" {
if logFile, err := os.Create(filepath.Join(dirName, filename)); err != nil {
log.Fatal("Unable to create logFile: ", err)
} else {
pLog.logFile = logFile
}
}
}
}

View file

@ -0,0 +1,117 @@
// 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 (
"os"
"path/filepath"
"strings"
log "github.com/sirupsen/logrus"
)
type schedPolicySwitchLogger struct {
baseElektronLogger
}
func newSchedPolicySwitchLogger(
config *loggerConfig,
b *baseLogData,
logType int,
prefix string,
logger *log.Logger,
logDir *logDirectory) *schedPolicySwitchLogger {
sLog := &schedPolicySwitchLogger{
baseElektronLogger: baseElektronLogger{
baseLogData: b,
config: struct {
Enabled bool
FilenameExtension string
AllowOnConsole bool
}{
Enabled: config.SPSConfig.Enabled,
FilenameExtension: config.SPSConfig.FilenameExtension,
AllowOnConsole: config.SPSConfig.AllowOnConsole,
},
logType: logType,
next: nil,
logger: logger,
logDir: logDir,
},
}
sLog.createLogFile(prefix)
return sLog
}
func (sLog schedPolicySwitchLogger) Log(logType int, level log.Level, message string) {
if sLog.logType == logType {
if sLog.isEnabled() {
if sLog.isAllowedOnConsole() {
sLog.logger.SetOutput(os.Stdout)
sLog.logger.WithFields(sLog.data).Log(level, message)
}
sLog.logger.SetOutput(sLog.logFile)
sLog.logger.WithFields(sLog.data).Log(level, message)
}
}
if sLog.next != nil {
sLog.next.Log(logType, level, message)
} else {
// Clearing the fields.
sLog.resetFields()
}
}
func (sLog schedPolicySwitchLogger) Logf(logType int, level log.Level, msgFmtString string, args ...interface{}) {
if sLog.logType == logType {
if sLog.isEnabled() {
if sLog.isAllowedOnConsole() {
sLog.logger.SetOutput(os.Stdout)
sLog.logger.WithFields(sLog.data).Logf(level, msgFmtString, args...)
}
sLog.logger.SetOutput(sLog.logFile)
sLog.logger.WithFields(sLog.data).Logf(level, msgFmtString, args...)
}
}
// Forwarding to next logger
if sLog.next != nil {
sLog.next.Logf(logType, level, msgFmtString, args...)
} else {
// Clearing the fields.
sLog.resetFields()
}
}
func (sLog *schedPolicySwitchLogger) createLogFile(prefix string) {
if sLog.isEnabled() {
filename := strings.Join([]string{prefix, sLog.getFilenameExtension()}, "")
dirName := sLog.logDir.getDirName()
if dirName != "" {
if logFile, err := os.Create(filepath.Join(dirName, filename)); err != nil {
log.Fatal("Unable to create logFile: ", err)
} else {
sLog.logFile = logFile
}
}
}
}

117
logging/schedTraceLogger.go Normal file
View file

@ -0,0 +1,117 @@
// 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 (
"os"
"path/filepath"
"strings"
log "github.com/sirupsen/logrus"
)
type schedTraceLogger struct {
baseElektronLogger
}
func newSchedTraceLogger(
config *loggerConfig,
b *baseLogData,
logType int,
prefix string,
logger *log.Logger,
logDir *logDirectory) *schedTraceLogger {
sLog := &schedTraceLogger{
baseElektronLogger: baseElektronLogger{
baseLogData: b,
config: struct {
Enabled bool
FilenameExtension string
AllowOnConsole bool
}{
Enabled: config.SchedTraceConfig.Enabled,
FilenameExtension: config.SchedTraceConfig.FilenameExtension,
AllowOnConsole: config.SchedTraceConfig.AllowOnConsole,
},
logType: logType,
next: nil,
logger: logger,
logDir: logDir,
},
}
sLog.createLogFile(prefix)
return sLog
}
func (sLog schedTraceLogger) Log(logType int, level log.Level, message string) {
if sLog.logType == logType {
if sLog.isEnabled() {
if sLog.isAllowedOnConsole() {
sLog.logger.SetOutput(os.Stdout)
sLog.logger.WithFields(sLog.data).Log(level, message)
}
sLog.logger.SetOutput(sLog.logFile)
sLog.logger.WithFields(sLog.data).Log(level, message)
}
}
if sLog.next != nil {
sLog.next.Log(logType, level, message)
} else {
// Clearing the fields.
sLog.resetFields()
}
}
func (sLog schedTraceLogger) Logf(logType int, level log.Level, msgFmtString string, args ...interface{}) {
if sLog.logType == logType {
if sLog.isEnabled() {
if sLog.isAllowedOnConsole() {
sLog.logger.SetOutput(os.Stdout)
sLog.logger.WithFields(sLog.data).Logf(level, msgFmtString, args...)
}
sLog.logger.SetOutput(sLog.logFile)
sLog.logger.WithFields(sLog.data).Logf(level, msgFmtString, args...)
}
}
// Forwarding to next logger
if sLog.next != nil {
sLog.next.Logf(logType, level, msgFmtString, args...)
} else {
// Clearing the fields.
sLog.resetFields()
}
}
func (sLog *schedTraceLogger) createLogFile(prefix string) {
if sLog.isEnabled() {
filename := strings.Join([]string{prefix, sLog.getFilenameExtension()}, "")
dirName := sLog.logDir.getDirName()
if dirName != "" {
if logFile, err := os.Create(filepath.Join(dirName, filename)); err != nil {
log.Fatal("Unable to create logFile: ", err)
} else {
sLog.logFile = logFile
}
}
}
}

View file

@ -0,0 +1,117 @@
// 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 (
"os"
"path/filepath"
"strings"
log "github.com/sirupsen/logrus"
)
type schedWindowLogger struct {
baseElektronLogger
}
func newSchedWindowLogger(
config *loggerConfig,
b *baseLogData,
logType int,
prefix string,
logger *log.Logger,
logDir *logDirectory) *schedWindowLogger {
sLog := &schedWindowLogger{
baseElektronLogger: baseElektronLogger{
baseLogData: b,
config: struct {
Enabled bool
FilenameExtension string
AllowOnConsole bool
}{
Enabled: config.SchedWindowConfig.Enabled,
FilenameExtension: config.SchedWindowConfig.FilenameExtension,
AllowOnConsole: config.SchedWindowConfig.AllowOnConsole,
},
logType: logType,
next: nil,
logger: logger,
logDir: logDir,
},
}
sLog.createLogFile(prefix)
return sLog
}
func (sLog schedWindowLogger) Log(logType int, level log.Level, message string) {
if sLog.logType == logType {
if sLog.isEnabled() {
if sLog.isAllowedOnConsole() {
sLog.logger.SetOutput(os.Stdout)
sLog.logger.WithFields(sLog.data).Log(level, message)
}
sLog.logger.SetOutput(sLog.logFile)
sLog.logger.WithFields(sLog.data).Log(level, message)
}
}
// Forwarding to next logger
if sLog.next != nil {
sLog.next.Log(logType, level, message)
} else {
// Clearing the fields.
sLog.resetFields()
}
}
func (sLog schedWindowLogger) Logf(logType int, level log.Level, msgFmtString string, args ...interface{}) {
if sLog.logType == logType {
if sLog.isEnabled() {
if sLog.isAllowedOnConsole() {
sLog.logger.SetOutput(os.Stdout)
sLog.logger.WithFields(sLog.data).Logf(level, msgFmtString, args...)
}
sLog.logger.SetOutput(sLog.logFile)
sLog.logger.WithFields(sLog.data).Logf(level, msgFmtString, args...)
}
}
if sLog.next != nil {
sLog.next.Logf(logType, level, msgFmtString, args...)
} else {
// Clearing the fields.
sLog.resetFields()
}
}
func (sLog *schedWindowLogger) createLogFile(prefix string) {
if sLog.isEnabled() {
filename := strings.Join([]string{prefix, sLog.getFilenameExtension()}, "")
dirName := sLog.logDir.getDirName()
if dirName != "" {
if logFile, err := os.Create(filepath.Join(dirName, filename)); err != nil {
log.Fatal("Unable to create logFile: ", err)
} else {
sLog.logFile = logFile
}
}
}
}

View file

@ -1,27 +1,28 @@
// 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
package types
type PCPLogger struct {
loggerObserverImpl
}
func (pl *PCPLogger) Log(message string) {
pl.logObserverSpecifics[pcpLogger].logFile.Println(message)
}
const (
CONSOLE = iota
PCP
SCHED_TRACE
SPS
SCHED_WINDOW
CLSFN_TASKDISTR_OVERHEAD
)

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
}