2019-12-09 20:05:28 -05:00
// 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/>.
//
2019-12-05 17:38:56 -05:00
package logging
2019-11-13 11:19:04 -05:00
import (
2019-12-05 21:32:37 -05:00
"github.com/pkg/errors"
2019-11-21 13:05:52 -05:00
"os"
2019-11-20 16:11:33 -05:00
"strings"
2019-11-20 13:33:46 -05:00
"time"
2019-11-26 14:24:20 -05:00
log "github.com/sirupsen/logrus"
2019-12-05 17:38:56 -05:00
. "github.com/spdfg/elektron/logging/types"
2019-11-13 11:19:04 -05:00
)
2019-12-05 23:02:08 -05:00
// var config loggerConfig
var formatter elektronFormatter
2019-12-05 21:32:37 -05:00
var elektronLoggerInstance elektronLogger
2019-11-13 11:19:04 -05:00
2019-12-05 21:32:37 -05:00
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
}
2019-11-13 11:19:04 -05:00
2019-12-05 21:32:37 -05:00
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
}
2019-12-06 12:59:35 -05:00
func ( l baseElektronLogger ) isAllowedOnConsole ( ) bool {
return l . config . AllowOnConsole
}
func ( l baseElektronLogger ) getFilenameExtension ( ) string {
return l . config . FilenameExtension
}
2019-12-05 21:32:37 -05:00
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 {
2019-11-20 13:33:46 -05:00
2019-11-26 14:24:20 -05:00
// Create the log directory.
2019-11-13 11:19:04 -05:00
startTime := time . Now ( )
formatter . TimestampFormat = "2006-01-02 15:04:05"
2019-11-20 16:11:33 -05:00
formattedStartTime := startTime . Format ( "20060102150405" )
2019-12-05 15:01:11 -05:00
logDir := & logDirectory { }
2019-11-21 13:47:22 -05:00
logDir . createLogDir ( prefix , startTime )
2019-11-26 14:24:20 -05:00
// Instantiate the logrus instance.
2019-11-21 14:02:47 -05:00
prefix = strings . Join ( [ ] string { prefix , formattedStartTime } , "_" )
2019-12-04 14:56:48 -05:00
logger := & log . Logger {
2019-11-21 13:05:52 -05:00
Out : os . Stderr ,
2019-11-21 14:12:53 -05:00
Level : log . DebugLevel ,
2019-11-21 13:05:52 -05:00
Formatter : & formatter ,
}
2019-11-13 14:08:52 -05:00
2019-11-26 14:24:20 -05:00
// Create a chain of loggers.
2019-12-04 13:16:48 -05:00
b := & baseLogData { data : log . Fields { } }
2019-12-05 21:32:37 -05:00
head := & baseElektronLogger { baseLogData : b }
// Read configuration from yaml.
2019-12-09 11:03:40 -05:00
if config , err := getConfig ( logConfigFilename ) ; err != nil {
2019-12-05 21:32:37 -05:00
return errors . Wrap ( err , "Failed to build logger" )
} else {
2019-12-05 23:02:08 -05:00
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 )
2019-12-05 21:32:37 -05:00
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 )
2019-11-13 11:19:04 -05:00
}