GO library that provides defaults and conventions for the zap logger
Go to file
2024-08-16 21:42:32 +00:00
.gitignore Initial commit 2024-08-09 04:38:50 +00:00
at_exit.go Initial Version 2024-08-09 14:25:34 -06:00
go.mod Update go.mod 2024-08-16 21:42:32 +00:00
go.sum Initial Version 2024-08-09 14:25:34 -06:00
LICENSE Initial commit 2024-08-09 04:38:50 +00:00
logger_test.go Initial Version 2024-08-09 14:25:34 -06:00
logger.go Initial Version 2024-08-09 14:25:34 -06:00
README.md Initial Version 2024-08-09 14:25:34 -06:00

cse-go-logging

Common golang logging module for use in CSE Go applications

Overview

This library will help you define a consistent logging experience within your Go applications. In a simple statement...

  • This library will define a Log Message
  • That is at a Log Level
  • Which is formatted in a defined Log Format
  • And forwarded to a Log Destination

This module is wrapper around Uber's Zap package. It serves more as a quick, consistent configuration than to add any additional functionality. For more details on how to use Zap, you can read the Uber Documentation

Additional Convenience Methods

I, for one, get annoyed with the following code:

MyObject, err := SomeInitializer(param1, param2)
if err != nil {
    panic(err)
}

Those last three lines are extremely common, and clutter up the code and really do not add to readability. So, I created a set of convenience methods where you can replace the error handling with OnError(err) and have it log your error, and panic or fatal automatically. The above code now becomes:

MyObject, err := SomeInitializer(param1, param2)
PanicOnError(err)

Its just athletics, but code is cleaner

Process Cleanup

Another issue this library is trying to make simpler is proper shutdown on Fatal and Panic.

In many ways GO follows functional not object-oriented patterns. If an object is created, and defer() was defined, it can have unwanted side effects. So, I often avoid it unless the object is created, used, then immediately discarded. So how to we safely handle longer running objects.

This module has a solution, and you can use piggyback this in your own programs if you like.

There is a struct called AtExit that is defined, and it has two methods on it:

  • Register
  • Cleanup

Register takes one parameter, a function name. The call will register that function to be called any time you run a PanicOnError or FatalOnError. The Cleanup function will call all functions "Registered" before issuing the fatal/panic call.

Usage Example:

var (
    db <pointer to some database connector>
)

func init() {
    db = // Insert your favorite database connect string here
    
    AtExit.Register(ShutDownDbConnection)
}

func ShutDownDbConnection() {
    logger.ErrorOnError(db.close())
}

Log Message

A log message, simply put will contain

  • a time and date stamp
  • a string indicating the Log Level
  • a Log message

Optional items that may appear include

  • A locator for where the message was requested in the code
  • Name Value pairs the code may want you to note
  • A stack trace giving even more detailed trace for error handling

Log Level

As with many level based logging libraries, this library will define the following log levels:

  • Debug: Recommendation: Tracing variable Values {user: Joe}
  • Info: Recommendation: Dev status message {DB Connection successful}
  • Warn: Recommendation: Non-Critical Errors {Got string, expected int, using 0}
  • Error: Recommendation: Serious error but not enough to stop program execution {Network Not Found, 404 errors}
  • Fatal: Recommendation: Serious Errors, program exist with error code 1
  • Panic: Recommendation: Full panic mode, {divide by 0}

Log Format

In this library, there will be two different output formats

  • Text: Single line per message with space delimiters
  • JSON: JSON format for easy automated processing

Example of Text Log Format:

2024-01-25T12:33:25.613-0700	INFO	cse-go-logging/logging_test.go:25	This is my log message

Example of JSON Log Format:

{
  "level": "error",
  "ts": "2024-01-25T13:10:01.025-0700",
  "caller": "cse-go-logging/logging_test.go:25",
  "msg": "This is my log message",
  "stacktrace": "cse-go-logging.(*LoggingTestSuite).Test_Placeholder\n\t/Users/a846682/GolandProjects/cse-go-logging/logging_test.go:25\nreflect.Value.call\n\t/Users/a846682/.asdf/installs/golang/1.21.6/go/src/reflect/value.go:596\nreflect.Value.Call\n\t/Users/a846682/.asdf/installs/golang/1.21.6/go/src/reflect/value.go:380\ngithub.com/stretchr/testify/suite.Run.func1\n\t/Users/a846682/.asdf/installs/golang/1.21.6/packages/pkg/mod/github.com/stretchr/testify@v1.8.1/suite/suite.go:175\ntesting.tRunner\n\t/Users/a846682/.asdf/installs/golang/1.21.6/go/src/testing/testing.go:1595"
}

Log Destination

Depending on the Log Environment you have configured your code to use, the log output will be sent to one of three different destinations:

  • StdErr: Development, Debug, and Production logs will send messages to standard error. These should appear on your output console within your machine
  • LogFile: Debug and Testing logs will create a file in your running directory named /log/debug
  • If you are running with a Testing log, the library will not use your live file system, but instead will use a memory map backed filesystem called LogFS and will exist as long as the test suite is running.

Log Environments

This library defines four predefined environments for your logging needs:

  • Development: for normal development operations. Logs will be text based, and log Info and higher messages. Output will be to StdErr
  • Debug: To increase the verbosity of logging, a Debug environment will also include Debug log messages, and will capture all logs to a logs/debug file within your working directory. In addition, stack traces will be turned on. So, errors can be more easily tracked.
  • Testing: This environment will operate exactly like Debug, except that it will not send logs to stderr, and will attach a memory backed file system that /logs/debug will be written to. This allows tests to easily pick up the output of log messages and test for proper logging
  • Production: Unlike the other environments, Production logs are JSON formatted.