// 2020 Rackspace, Inc. // // Licensed under the Apache License, Version 2.0 (the "License"): you may // not use this file except in compliance with the License. You may obtain // a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the // License for the specific language governing permissions and limitations // under the License. package log import ( "fmt" "strings" "github.com/labstack/gommon/color" ) const ( // ErrorLvl: failure happened ans should be reviewed. ErrorLvl = iota // WarnLvl: non-critical; should be reviewed. WarnLvl // InfoLvl level is a general entry about what's going on inside the application InfoLvl // DebugLvl level is only enabled when debugging. Very verbose logging. DebugLvl // TraceLvl level designates finer-grained informational events than the Debug. TraceLvl ) // Print function will utilize logrus to print the output to terminal for the envLog type. func (e Entry) Print(minimumLevel uint32) { if e.Type <= minimumLevel { fmt.Println(e.ToTerminal()) } } // String method will return a string format of the LogEntry struct func (e Entry) String() string { if e.Message != "" { e.Message = ":" + e.Message } return fmt.Sprintf("[%s] %s%s", e.ID, e.Func, e.Message) } // ToTerminal method will return a string format of the LogEntry struct func (e Entry) ToTerminal() string { if e.Message != "" { e.Message = ":" + e.Message } prefix := "UNKN" switch e.Type { case ErrorLvl: prefix = color.Red("ERRO") case WarnLvl: prefix = color.Yellow("WARN") case InfoLvl: prefix = color.Cyan("INFO") case DebugLvl: prefix = color.Magenta("DEBU") case TraceLvl: prefix = color.White("TRAC") } return fmt.Sprintf("%s: [%s] %s%s", prefix, color.Green(e.ID), color.Blue(e.Func), e.Message) } type ( // LogEntry struct defines a type of log received from processing // gathering and changes to environment manager Entry struct { Type uint32 `json:"-"` Func string `json:"action"` ID string `json:"id"` Message string `json:"message"` } // Collector is the type that gets initialized for this log package. Collector struct { Logs []Entry `json:"log_entries"` Errors []string `json:"errors"` } ) // Init is a helper method to create a new empty collector func Init() *Collector { return &Collector{ Logs: make([]Entry, 0), Errors: make([]string, 0), } } // Log is a helper method attached to the Collector pointer receiver that is used to append // on an additional log message to the Collector client. func (c *Collector) Log(state uint32, fn string, id interface{}, messages ...string) { if c.Logs == nil { c.Logs = make([]Entry, 0) } c.Logs = append(c.Logs, Entry{ Type: state, Func: fn, ID: fmt.Sprintf("%v", id), Message: strings.Join(messages, ":"), }) } // Error is a wrapper method to add the error message onto the // LogEntries func (c *Collector) Error(f string, id interface{}, err error) { if c.Errors == nil { c.Errors = make([]string, 0) } c.Errors = append(c.Errors, fmt.Sprintf("[%v] %s=%s", id, f, err)) } // Warn is a helper method that will append a log message on with a level to Warn func (c *Collector) Warn(fn string, id interface{}, messages ...string) { c.Log(WarnLvl, fn, id, messages...) } // Info is a helper method that will append a log message on with a level to Info func (c *Collector) Info(fn string, id interface{}, messages ...string) { c.Log(InfoLvl, fn, id, messages...) } // Debug is a helper method that will append a log message on with a level to Debug func (c *Collector) Debug(fn string, id interface{}, messages ...string) { c.Log(DebugLvl, fn, id, messages...) } // Trace is a helper method that will append a log message on with a level to Trace func (c *Collector) Trace(fn string, id interface{}, messages ...string) { c.Log(TraceLvl, fn, id, messages...) }