Skip to content

Commit

Permalink
Adds logging
Browse files Browse the repository at this point in the history
  • Loading branch information
kyallanum committed Jan 1, 2024
1 parent 1f53304 commit 1f727fd
Show file tree
Hide file tree
Showing 10 changed files with 200 additions and 29 deletions.
24 changes: 19 additions & 5 deletions cmd/cmd_test.go
Original file line number Diff line number Diff line change
@@ -1,20 +1,25 @@
package cmd

import (
"io"
"os"
"testing"

config "github.com/kyallanum/athena/models/config"
logs "github.com/kyallanum/athena/models/logs"
"github.com/sirupsen/logrus"
)

func TestResolveFile(t *testing.T) {
logger := logrus.New()
logger.SetOutput(io.Discard)

os.Stdout, _ = os.Open(os.DevNull)
defer os.Stdout.Close()
logFile, _ := logs.LoadLogFile("../examples/apt-term.log")
configuration, _ := config.CreateConfiguration("../examples/apt-term-config.json")

_, err := resolveLogFile(logFile, configuration)
_, err := resolveLogFile(logFile, configuration, logger)

if err != nil {
t.Errorf("An error occurred while resolving log file: %s", err)
Expand All @@ -28,47 +33,56 @@ func TestResolveLogFileBadLog(t *testing.T) {
logFile, _ := logs.LoadLogFile("../examples/apt-term-bad.log")
configuration, _ := config.CreateConfiguration("../examples/apt-term-config.json")

_, err := resolveLogFile(logFile, configuration)
_, err := resolveLogFile(logFile, configuration, nil)

if err.Error() != "log file contains no contents" {
t.Errorf("Error was not properly returned when checking log file contents")
}
}

func TestResolveLogFileBadConfig(t *testing.T) {
logger := logrus.New()
logger.SetOutput(io.Discard)

os.Stdout, _ = os.Open(os.DevNull)
defer os.Stdout.Close()

logFile, _ := logs.LoadLogFile("../examples/apt-term.log")
configuration, _ := config.CreateConfiguration("../examples/apt-term-config-bad.json")

_, err := resolveLogFile(logFile, configuration)
_, err := resolveLogFile(logFile, configuration, logger)

if err.Error() != "configuration file has no contents" {
t.Errorf("Error was not properly returned when checking configuration contents")
}
}

func TestResolveLogFileNoConfigName(t *testing.T) {
logger := logrus.New()
logger.SetOutput(io.Discard)

logFile, _ := logs.LoadLogFile("../examples/apt-term.log")
configuration := &config.Configuration{
Rules: make([]config.Rule, 1),
}

_, err := resolveLogFile(logFile, configuration)
_, err := resolveLogFile(logFile, configuration, logger)

if err.Error() != "configuration file contains no log name" {
t.Errorf("Error was not properly returned when checking configuration name")
}
}

func TestResolveLogFileNoConfigRules(t *testing.T) {
logger := logrus.New()
logger.SetOutput(io.Discard)

logFile, _ := logs.LoadLogFile("../examples/apt-term.log")
configuration := &config.Configuration{
Name: "test",
}

_, err := resolveLogFile(logFile, configuration)
_, err := resolveLogFile(logFile, configuration, logger)
if err.Error() != "configuration does not have any rules" {
t.Errorf("Error was not properly returned when checking configuration rules")
}
Expand Down
47 changes: 28 additions & 19 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,13 @@ import (

config "github.com/kyallanum/athena/models/config"
library "github.com/kyallanum/athena/models/library"
logger_pkg "github.com/kyallanum/athena/models/logger"
logs "github.com/kyallanum/athena/models/logs"
"github.com/sirupsen/logrus"
"github.com/spf13/cobra"
)

var configFile, logFile string
var configFile, logFile, logOutput string

var rootCmd = &cobra.Command{
Use: "athena [flags]",
Expand All @@ -28,7 +30,7 @@ var rootCmd = &cobra.Command{
},
}

func Execute() error {
func Execute(logger *logrus.Logger) error {
errCheck := func(err error) {
if err != nil {
panic(err)
Expand All @@ -37,33 +39,40 @@ func Execute() error {

err := rootCmd.Execute()
errCheck(err)
fmt.Println("Athena v1.0.0 Starting")

fmt.Println("Getting Configuration File: ", configFile, "...")
if logOutput != "" {
logger_pkg.AddFileLogger(logger, logOutput)
}

logger.Info("Athena v1.0.0 Starting")

logger.Info("Getting Configuration File: ", configFile, "...")
configuration, err := config.CreateConfiguration(configFile)
errCheck(err)
fmt.Println("Configuration Loaded")
logger.Info("Configuration Loaded")

fmt.Println("Loading Log File: ", logFile, "... ")
logger.Info("Loading Log File: ", logFile, "... ")
logFileContents, err := logs.LoadLogFile(logFile)
errCheck(err)
fmt.Println("Log File Loaded")
logger.Info("Log File Loaded")

library, err := resolveLogFile(logFileContents, configuration)
library, err := resolveLogFile(logFileContents, configuration, logger)
errCheck(err)

err = printSummary(library)
err = printSummary(library, logger)
errCheck(err)

return nil
}

func init() {
rootCmd.Flags().StringVarP(&configFile, "config", "c", os.Getenv("ATHENA_CONFIG_FILE"), "")
rootCmd.Flags().StringVarP(&logFile, "log-file", "l", os.Getenv("ATHENA_LOG_FILE"), "")
rootCmd.Flags().StringVarP(&logFile, "file", "f", os.Getenv("ATHENA_LOG_FILE"), "")
rootCmd.Flags().StringVarP(&logOutput, "log-output", "l", os.Getenv("ATHENA_LOG_OUTPUT"), "")
}

func resolveLogFile(contents *logs.LogFile, configuration *config.Configuration) (*library.Library, error) {
func resolveLogFile(contents *logs.LogFile, configuration *config.Configuration, logger *logrus.Logger) (*library.Library, error) {

wrapError := func(err error) error {
return fmt.Errorf("unable to resolve log file: \n\t%w", err)
}
Expand All @@ -80,7 +89,7 @@ func resolveLogFile(contents *logs.LogFile, configuration *config.Configuration)

ret_library := library.New(configuration.Name)

fmt.Println("Resolving Log File")
logger.Info("Resolving Log File")
for i := 0; i < len(configuration.Rules); i++ {
currentRuleData, err := config.ResolveRule(contents, &configuration.Rules[i])
if err != nil {
Expand All @@ -90,12 +99,12 @@ func resolveLogFile(contents *logs.LogFile, configuration *config.Configuration)
ret_library.AddRuleData(configuration.Rules[i].Name, currentRuleData)
}

fmt.Println("Log File Resolved")
logger.Info("Log File Resolved")

return ret_library, nil
}

func printSummary(library *library.Library) error {
func printSummary(library *library.Library, logger *logrus.Logger) error {
wrapError := func(err error) error {
return fmt.Errorf("unable to print summary: \n\t%w", err)
}
Expand All @@ -105,20 +114,20 @@ func printSummary(library *library.Library) error {
return wrapError(err)
}

fmt.Printf("\n--------------- %s Log File Summary ---------------\n", libraryName)
logger.Infof("\n--------------- %s Log File Summary ---------------\n", libraryName)
libraryKeys := library.LibraryKeys()
for _, rule := range libraryKeys {
fmt.Printf("Rule: %s\n", rule)
logger.Infof("Rule: %s\n", rule)
ruleData, _ := library.RuleData(rule)
summaryDataLen := ruleData.SummaryDataLen()
if summaryDataLen == 0 {
fmt.Println("No summary lines provided.")
logger.Info("No summary lines provided.")
} else {
for i := 0; i < summaryDataLen; i++ {
fmt.Println("\t", ruleData.SummaryData(i))
logger.Info("\t", ruleData.SummaryData(i))
}
}
fmt.Println()
logger.Info()
}

return nil
Expand Down
2 changes: 2 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@ go 1.21

require (
github.com/davidmytton/url-verifier v1.0.0
github.com/sirupsen/logrus v1.9.3
github.com/spf13/cobra v1.8.0
)

require (
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 // indirect
)
8 changes: 8 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so=
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davidmytton/url-verifier v1.0.0 h1:TIdwZ+rWVnfnJPMD/DclwEJ0XewV4jkr0qEcX/58n+4=
Expand All @@ -10,12 +11,19 @@ github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLf
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0=
github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 h1:0A+M6Uqn+Eje4kHMK80dtF3JCXC4ykBgQG4Fe06QRhQ=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
10 changes: 5 additions & 5 deletions main.go
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
package main

import (
"fmt"
"os"

"github.com/kyallanum/athena/cmd"
"github.com/kyallanum/athena/models/logger"
)

func main() {
logger := logger.New()

defer func() {
if err := recover(); err != nil {
fmt.Fprintln(os.Stderr, "\nAn error occured: ", err)
logger.Fatalf("\nAn error occured: \n\t%s", err)
}
}()

if err := cmd.Execute(); err != nil {
if err := cmd.Execute(logger); err != nil {
panic(err)
}
}
17 changes: 17 additions & 0 deletions models/logger/file_formatter.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package logger

import (
"fmt"

"github.com/sirupsen/logrus"
)

type FileFormatter struct {
logrus.TextFormatter
TimestampFormat string
}

func (formatter *FileFormatter) Format(entry *logrus.Entry) ([]byte, error) {
timestamp := entry.Time.Format(formatter.TimestampFormat)
return []byte(fmt.Sprintf("%s %s: %s\n", timestamp, entry.Level.String(), entry.Message)), nil
}
26 changes: 26 additions & 0 deletions models/logger/fomatter_hook.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package logger

import (
"io"

"github.com/sirupsen/logrus"
)

type FormatterHook struct {
Writer io.Writer
LogLevels []logrus.Level
Formatter logrus.Formatter
}

func (hook *FormatterHook) Fire(entry *logrus.Entry) error {
line, err := hook.Formatter.Format(entry)
if err != nil {
return err
}
_, err = hook.Writer.Write(line)
return err
}

func (hook *FormatterHook) Levels() []logrus.Level {
return hook.LogLevels
}
63 changes: 63 additions & 0 deletions models/logger/logger.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package logger

import (
"io"
"os"

"github.com/sirupsen/logrus"
)

func AddFileLogger(logger *logrus.Logger, fileName string) {
file, err := os.OpenFile(fileName, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0644)
if err != nil {
logger.Fatalf("An error occurred: \n\t%s", err.Error())
}
defer file.Close()

FileHook := &FormatterHook{
Writer: file,
LogLevels: []logrus.Level{
logrus.InfoLevel,
logrus.DebugLevel,
logrus.WarnLevel,
logrus.ErrorLevel,
logrus.FatalLevel,
logrus.PanicLevel,
},
Formatter: &FileFormatter{
TimestampFormat: "01/02/2006 15:03:04",
},
}

logger.AddHook(FileHook)
}

func New(fileName ...string) *logrus.Logger {
newLogger := logrus.New()
newLogger.SetOutput(io.Discard)
newLogger.SetLevel(logrus.InfoLevel)

StdoutHook := &FormatterHook{
Writer: os.Stdout,
LogLevels: []logrus.Level{
logrus.InfoLevel,
},
Formatter: &StdoutFormatter{},
}
newLogger.AddHook(StdoutHook)

StderrHook := &FormatterHook{
Writer: os.Stderr,
LogLevels: []logrus.Level{
logrus.ErrorLevel,
logrus.FatalLevel,
logrus.PanicLevel,
},
Formatter: &StderrFormatter{
TimestampFormat: "01/02/2006 15:04:05",
},
}
newLogger.AddHook(StderrHook)

return newLogger
}
Loading

0 comments on commit 1f727fd

Please sign in to comment.