Skip to content

Commit

Permalink
add file logger
Browse files Browse the repository at this point in the history
  • Loading branch information
creativeprojects committed Jul 7, 2020
1 parent fb3489c commit b31c4cf
Show file tree
Hide file tree
Showing 8 changed files with 277 additions and 90 deletions.
14 changes: 0 additions & 14 deletions array/string.go

This file was deleted.

120 changes: 120 additions & 0 deletions clog/file.go
@@ -0,0 +1,120 @@
package clog

import (
"log"
"os"
)

// FileLog logs messages to a file
type FileLog struct {
quiet bool
verbose bool
file *os.File
}

// NewFileLog creates a new file logger
// Remember to Close() the logger at the end
func NewFileLog(filename string) (*FileLog, error) {
file, err := os.OpenFile(filename, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0644)
if err != nil {
return nil, err
}
logger := &FileLog{
file: file,
}
// also redirect the standard logger to the file
SetOutput(file)
return logger, nil
}

// Close the logfile when no longer needed
// please note this method reinstate the NULL logger as the default logger
func (l *FileLog) Close() {
if l.file != nil {
l.file.Sync()
l.file.Close()
l.file = nil
}
// make sure any other call to the logger won't panic
defaultLog = &NullLog{}
// and reset the standard logger
SetOutput(os.Stdout)
}

// Quiet will only display warnings and errors
func (l *FileLog) Quiet() {
l.quiet = true
l.verbose = false
}

// Verbose will display debugging information
func (l *FileLog) Verbose() {
l.verbose = true
l.quiet = false
}

// Debug sends debugging information
func (l *FileLog) Debug(v ...interface{}) {
if !l.verbose {
return
}
l.message(DebugLevel, v...)
}

// Debugf sends debugging information
func (l *FileLog) Debugf(format string, v ...interface{}) {
if !l.verbose {
return
}
l.messagef(DebugLevel, format, v...)
}

// Info logs some noticeable information
func (l *FileLog) Info(v ...interface{}) {
if l.quiet {
return
}
l.message(InfoLevel, v...)
}

// Infof logs some noticeable information
func (l *FileLog) Infof(format string, v ...interface{}) {
if l.quiet {
return
}
l.messagef(InfoLevel, format, v...)
}

// Warning send some important message to the console
func (l *FileLog) Warning(v ...interface{}) {
l.message(WarningLevel, v...)
}

// Warningf send some important message to the console
func (l *FileLog) Warningf(format string, v ...interface{}) {
l.messagef(WarningLevel, format, v...)
}

// Error sends error information to the console
func (l *FileLog) Error(v ...interface{}) {
l.message(ErrorLevel, v...)
}

// Errorf sends error information to the console
func (l *FileLog) Errorf(format string, v ...interface{}) {
l.messagef(ErrorLevel, format, v...)
}

func (l *FileLog) message(level int, v ...interface{}) {
v = append([]interface{}{getLevelName(level)}, v...)
log.Println(v...)
}

func (l *FileLog) messagef(level int, format string, v ...interface{}) {
log.Printf(getLevelName(level)+" "+format+"\n", v...)
}

// Verify interface
var (
_ Log = &FileLog{}
)
41 changes: 40 additions & 1 deletion clog/log.go
@@ -1,5 +1,11 @@
package clog

import (
"io"
"log"
"os"
)

// LogLevel
const (
DebugLevel = iota
Expand All @@ -20,16 +26,49 @@ type Log interface {
Errorf(format string, v ...interface{})
}

// Verbosity represents the verbose logger interface
type Verbosity interface {
Quiet()
Verbose()
}

var (
// default to null logger for tests
defaultLog Log = &NullLog{}
defaultLog Log = &NullLog{}
defaultOutput io.Writer = os.Stdout
)

func getLevelName(level int) string {
switch level {
case DebugLevel:
return "DEBUG"
case InfoLevel:
return "INFO "
case WarningLevel:
return "WARN "
case ErrorLevel:
return "ERROR"
default:
return ""
}
}

// SetDefaultLogger sets the logger when using the package methods
func SetDefaultLogger(log Log) {
defaultLog = log
}

// SetOutput sets the default output of the current logger
func SetOutput(w io.Writer) {
defaultOutput = w
log.SetOutput(w)
}

// GetOutput returns the default output of the current logger
func GetOutput() io.Writer {
return defaultOutput
}

// Debug sends debugging information
func Debug(v ...interface{}) {
defaultLog.Debug(v...)
Expand Down
15 changes: 0 additions & 15 deletions clog/test.go
Expand Up @@ -78,21 +78,6 @@ func (l *TestLog) messagef(level int, format string, v ...interface{}) {
l.t.Logf(getLevelName(level)+" "+format, v...)
}

func getLevelName(level int) string {
switch level {
case DebugLevel:
return "DEBUG"
case InfoLevel:
return "INFO"
case WarningLevel:
return "WARNING"
case ErrorLevel:
return "ERROR"
default:
return ""
}
}

// Verify interface
var (
_ Log = &TestLog{}
Expand Down
7 changes: 6 additions & 1 deletion examples/windows.yaml
@@ -1,6 +1,11 @@
global:
priority: low
min-memory: 0
min-memory: 10

groups:
double:
- self
- self

default:
repository: "d:\\backup"
Expand Down
4 changes: 3 additions & 1 deletion flags.go
Expand Up @@ -16,6 +16,7 @@ type commandLineFlags struct {
config string
format string
name string
logFile string
noAnsi bool
theme string
resticArgs []string
Expand Down Expand Up @@ -47,11 +48,12 @@ func loadFlags() (*pflag.FlagSet, commandLineFlags) {
flagset.StringVarP(&flags.config, "config", "c", constants.DefaultConfigurationFile, "configuration file")
flagset.StringVarP(&flags.format, "format", "f", "", "file format of the configuration (default is to use the file extension)")
flagset.StringVarP(&flags.name, "name", "n", constants.DefaultProfileName, "profile name")
flagset.StringVarP(&flags.logFile, "log", "l", "", "logs into a file instead of the console")

flagset.BoolVar(&flags.noAnsi, "no-ansi", false, "disable ansi control characters (disable console colouring)")
flagset.StringVar(&flags.theme, "theme", constants.DefaultTheme, "console colouring theme (dark, light, none)")

flagset.BoolVarP(&flags.help, "wait", "w", false, "wait at the end until the user presses the enter key")
flagset.BoolVarP(&flags.wait, "wait", "w", false, "wait at the end until the user presses the enter key")

if runtime.GOOS == "windows" {
// flag for internal use only
Expand Down
55 changes: 55 additions & 0 deletions logger.go
@@ -0,0 +1,55 @@
package main

import (
"github.com/creativeprojects/resticprofile/clog"
"github.com/creativeprojects/resticprofile/remote"
)

func setupRemoteLogger(flags commandLineFlags) {
client := remote.NewClient(flags.parentPort)
logger := clog.NewRemoteLog(client)
logger.SetPrefix("elevated user: ")
clog.SetDefaultLogger(logger)
}

func setupFileLogger(flags commandLineFlags) (*clog.FileLog, error) {
logger, err := clog.NewFileLog(flags.logFile)
if err != nil {
return nil, err
}
clog.SetDefaultLogger(logger)
setupVerbosity(flags, logger)
return logger, nil
}

func setupConsoleLogger(flags commandLineFlags) {
logger := clog.NewConsoleLog()
if flags.theme != "" {
logger.SetTheme(flags.theme)
}
if flags.noAnsi {
logger.Colorize(false)
}
clog.SetDefaultLogger(logger)
setupVerbosity(flags, logger)
}

func setupVerbosity(flags commandLineFlags, logger clog.Verbosity) {
if flags.quiet && flags.verbose {
coin := ""
if randomBool() {
coin = "verbose"
flags.quiet = false
} else {
coin = "quiet"
flags.verbose = false
}
clog.Warningf("you specified -quiet (-q) and -verbose (-v) at the same time. So let's flip a coin! and selection is ... %s.", coin)
}
if flags.quiet {
logger.Quiet()
}
if flags.verbose {
logger.Verbose()
}
}

0 comments on commit b31c4cf

Please sign in to comment.