diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..6707d7f --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,9 @@ +#### What does this PR do + +#### Description of Task to be completed + +#### How should this be manually tested + +#### Any background context you want to add + +#### Screenshots diff --git a/.gitignore b/.gitignore index 6226bf4..ed5921d 100644 --- a/.gitignore +++ b/.gitignore @@ -15,4 +15,7 @@ # vendor/ # Goland -/.idea \ No newline at end of file +/.idea + +# Testing Log Directory +/logs \ No newline at end of file diff --git a/README.md b/README.md index 1ce4412..1a79cda 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,9 @@ In Egyptian Mythology, Thoth was the Egyptian ibis-headed god of knowledge, magi Thoth is an error logger for go. It helps log errors to a log file so you can go back to find how why and when something breaks in production. +>**NOTE** +>Log file can be either a `.log` file or a `.json` file at the time of this release + # Installation You can install thoth by running diff --git a/example/main.go b/example/main.go index fa11263..ea33622 100644 --- a/example/main.go +++ b/example/main.go @@ -2,25 +2,36 @@ package main import ( "fmt" - "github.com/ichtrojan/thoth" - "log" "net/http" + + "github.com/ichtrojan/thoth" ) func main() { - logger := thoth.Init() + json, err := thoth.Init("json") + + if err != nil { + fmt.Println(err) + } + + file, err := thoth.Init("log") + + if err != nil { + fmt.Println(err) + } http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { _, err := fmt.Fprintf(w, "Hello, Testing from Thoth") if err != nil { - log.Fatal(err) + json.Log(err) } fmt.Println("Endpoint served") }) if err := http.ListenAndServe(":8888", nil); err != nil { - logger.Log(err) + json.Log(err) + file.Log(err) } } diff --git a/logs/error.log b/logs/error.log deleted file mode 100644 index 196c067..0000000 --- a/logs/error.log +++ /dev/null @@ -1,3 +0,0 @@ -[2020-01-05 14:35:36] listen tcp :8888: bind: address already in use -[2020-01-05 14:35:39] listen tcp :8888: bind: address already in use -[2020-01-05 14:35:41] listen tcp :8888: bind: address already in use diff --git a/thoth.go b/thoth.go index 6e32a83..304c2ff 100644 --- a/thoth.go +++ b/thoth.go @@ -1,7 +1,10 @@ package thoth import ( + "encoding/json" + "errors" "fmt" + "io/ioutil" "os" "time" ) @@ -10,18 +13,32 @@ const directory = "logs" type Config struct { directory string + filetype string } -func Init() Config { +func Init(filetype string) (Config, error) { + var config Config + if _, err := os.Stat(directory); os.IsNotExist(err) { err = os.MkdirAll(directory, 0755) if err != nil { - fmt.Println(err) + return config, err } } - path := fmt.Sprintf("%s/error.log", directory) + var filename string + + switch filetype { + case "log": + filename = "error.log" + case "json": + filename = "error.json" + default: + return config, errors.New("adapter not defined") + } + + path := fmt.Sprintf("%s/%s", directory, filename) var _, err = os.Stat(path) @@ -35,33 +52,75 @@ func Init() Config { defer file.Close() } - return Config{directory: path} + return Config{directory: path, filetype: filetype}, nil } func (config Config) Log(error error) { + switch config.filetype { + case "log": + _ = config.logFile(error) + case "json": + _ = config.logJson(error) + default: + return + } +} + +func (config Config) logFile(error error) error { path := config.directory var file, err = os.OpenFile(path, os.O_APPEND|os.O_WRONLY, 0644) if err != nil { - fmt.Println(err) + return err } defer file.Close() - newError := fmt.Sprintf("[%s] %s", time.Now().Format("2006-01-02 15:04:05"), error) + newError := fmt.Sprintf("[%s] %s", time.Now().Format("2006-01-02 15:04:05"), error.Error()) _, err = fmt.Fprintln(file, newError) if err != nil { - fmt.Println(err) + return err } err = file.Sync() if err != nil { - fmt.Println(err) + return err + } + + return nil +} + +func (config Config) logJson(error error) error { + path := config.directory + + var file, err = ioutil.ReadFile(path) + + if err != nil { + return err + } + + var jsonData []map[string]interface{} + + _ = json.Unmarshal(file, &jsonData) + + newError := map[string]interface{}{ + "timestamp": time.Now().Format("2006-01-02 15:04:05"), + "error": error.Error(), } - return + jsonData = append(jsonData, newError) + + jsonString, err := json.Marshal(jsonData) + + if err != nil { + return err + } + + _ = ioutil.WriteFile(path, jsonString, os.ModePerm) + + return nil }