Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

adding option to reset back to default prefixer value #4

Merged
merged 1 commit into from
Feb 24, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
adding option to reset back to default prefixer value
nhennigan committed Feb 24, 2023
commit b1a342f2e8d77c3a0adb332a9ffeb7fc05b165b0
102 changes: 74 additions & 28 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,32 +1,38 @@
- [CNI Log](#cni-log)
- [Usage](#usage)
- [Importing cni-log](#importing-cni-log)
- [Customizing the logging prefix/header](#customizing-log-prefix)
- [Public Types & Functions](#public-types--functions)
- [Customizing the logging prefix/header](#customizing-the-logging-prefixheader)
- [Public Types \& Functions](#public-types--functions)
- [Types](#types)
- [Level](#level)
- [Prefixer](#prefixer)
- [LogOptions](#logoptions)
- [Public setup functions](#public-setup-functions)
- [SetLogLevel](#setloglevel)
- [GetLogLevel](#getloglevel)
- [StringToLevel](#stringtolevel)
- [String](#string)
- [SetLogStderr](#setlogstderr)
- [SetLogOptions](#setlogoptions)
- [SetLogFile](#setlogfile)
- [SetOutput](#setoutput)
- [SetPrefixer](#setprefixer)
- [SetDefaultPrefixer](#setdefaultprefixer)
- [Logging functions](#logging-functions)
- [Default values](#default-values)

## CNI Log

The purpose of this package is to perform logging for CNI projects in NPWG. Cni-log provides general logging functionality for Container Network Interfaces (CNI). Messages can be logged to a log file and/or to standard error.

## Usage

The package can function out of the box as most of its configurations have [default values](#default-values). Just call any of the [logging functions](#logging-functions) to start logging. To further define log settings such as the log file path, the log level, as well as the lumberjack logger object, continue on to the [public functions below](#public-types--functions).

### Importing cni-log

Import cni-log in your go file:

```go
import (
...
@@ -38,6 +44,7 @@ import (
Then perform a `go mod tidy` to download the package.

### Customizing the logging prefix/header

CNI-log allows users to modify the logging prefix/header. The default prefix is in the following format:

```
@@ -49,13 +56,17 @@ E.g.
```
2022-10-11T13:09:57Z [info] This is a log message with INFO log level
```
To change the prefix used by cni-log, you will need to provide the implementation of how the prefix string would be built. To do so you will need to create an object of type [``Prefixer``](#prefixer). ``Prefixer`` is an interface with one function:

To change the prefix used by cni-log, you will need to provide the implementation of how the prefix string would be built. To do so you will need to create an object of type [``Prefixer``](#prefixer). ``Prefixer`` is an interface with one function:

```go
CreatePrefix(Level) string
```

Implement the above function with the code that would build the prefix string. In order for CNI-Log to use your custom prefix you will then need to pass in your custom prefix object using the [``SetPrefixer``](#setprefixer) function.

Below is sample code on how to build a custom prefix:

```go
package main
import (
@@ -66,48 +77,53 @@ import (

// custom prefix type
type customPrefix struct {
prefixFormat string
timeFormat string
currentFile string
prefixFormat string
timeFormat string
currentFile string
}

func main() {
// cni-log configuration
logging.SetLogFile("samplelog.log")
logging.SetLogLevel(logging.VerboseLevel)
logging.SetLogStderr(true)
logging.SetLogFile("samplelog.log")
logging.SetLogLevel(logging.VerboseLevel)
logging.SetLogStderr(true)

// Creating the custom prefix object
prefix := &customPrefix{
prefixFormat: "%s | %s | %s | ",
timeFormat: time.RFC850,
currentFile: "main.go",
}
logging.SetPrefixer(prefix) // Tell cni-log to use your custom prefix object
prefix := &customPrefix{
prefixFormat: "%s | %s | %s | ",
timeFormat: time.RFC850,
currentFile: "main.go",
}
logging.SetPrefixer(prefix) // Tell cni-log to use your custom prefix object

// Log messages
logging.Infof("Info log message")
logging.Warningf("Warning log message")
logging.Infof("Info log message")
logging.Warningf("Warning log message")
}

// Implement the CreatePrefix function using your custom prefix object. This function will be called by CNI-Log
// to build the prefix string.
func (p *customPrefix) CreatePrefix(loggingLevel logging.Level) string {
currentTime := time.Now()
return fmt.Sprintf(p.prefixFormat, currentTime.Format(p.timeFormat), p.currentFile, loggingLevel)
currentTime := time.Now()
return fmt.Sprintf(p.prefixFormat, currentTime.Format(p.timeFormat), p.currentFile, loggingLevel)
}
```

### Public Types & Functions

#### Types

##### Level

```go
// Level type
type Level int
```

Defines the type that will represent the different log levels

##### Prefixer

```go
type Prefixer interface {
CreatePrefix(Level) string
@@ -117,25 +133,29 @@ type Prefixer interface {
Defines an interface that contains one function: ``CreatePrefix(Level) string``. Implementing this function allows you to build your own custom prefix.

##### LogOptions

```go
// LogOptions defines the configuration of the lumberjack logger
type LogOptions struct {
MaxAge *int `json:"maxAge,omitempty"`
MaxSize *int `json:"maxSize,omitempty"`
MaxBackups *int `json:"maxBackups,omitempty"`
Compress *bool `json:"compress,omitempty"`
MaxAge *int `json:"maxAge,omitempty"`
MaxSize *int `json:"maxSize,omitempty"`
MaxBackups *int `json:"maxBackups,omitempty"`
Compress *bool `json:"compress,omitempty"`
}
```
For further details of each field, see the [lumberjack documentation](https://github.com/natefinch/lumberjack).

For further details of each field, see the [lumberjack documentation](https://github.com/natefinch/lumberjack).

To view the default values of each field, go to the "[Default values](#default-values)" section

#### Public setup functions

##### SetLogLevel

```go
func SetLogLevel(level Level)
```

Sets the log level. The valid log levels are:
| int | string | Level |
| --- | --- | --- |
@@ -146,57 +166,82 @@ Sets the log level. The valid log levels are:
| 5 | debug | DebugLevel |
| 6 | verbose | VerboseLevel |

The log levels above are in ascending order of verbosity. For example, setting the log level to InfoLevel would mean "panic", "error", warning", and "info" messages will get logged while "debug", and "verbose" will not.
The log levels above are in ascending order of verbosity. For example, setting the log level to InfoLevel would mean "panic", "error", warning", and "info" messages will get logged while "debug", and "verbose" will not.

##### GetLogLevel

```go
func GetLogLevel() Level
```

Returns the current log level

##### StringToLevel

```go
func StringToLevel(level string) Level
```

Returns the Level equivalent of a string. See SetLogLevel for valid levels.

##### String

```go
func (l Level) String() string
```

Returns the string representation of a log level

##### SetLogStderr

```go
func SetLogStderr(enable bool)
```
This function allows you to enable/disable logging to standard error.

This function allows you to enable/disable logging to standard error.

##### SetLogOptions

```go
func SetLogOptions(options *LogOptions)
```

Configures the lumberjack object based on the lumberjack configuration data set in the ``logOptions`` object (see ``logOptions`` struct above).

##### SetLogFile

```go
func SetLogFile(filename string)
```

Configures where logs will be written to. If an empty/invalid filepath (e.g. insufficient permissions), or a symbolic link is passed into the function, the default log filepath is used.

##### SetOutput

```go
func SetOutput(out io.Writer)
```

Set custom output. Calling this function will discard any previously set LogOptions.

##### SetPrefixer

```go
func SetPrefixer(p Prefixer)
```
This function allows you to override the default logging prefix with a custom prefix.

This function allows you to override the default logging prefix with a custom prefix.

##### SetDefaultPrefixer

```go
func SetDefaultPrefixer()
```

This function allows you to return to the default logging prefix.

#### Logging functions

```go
// Errorf prints logging if logging level >= error
func Errorf(format string, a ...interface{}) error
@@ -215,11 +260,12 @@ func Verbosef(format string, a ...interface{})
```

### Default values

| Variable | Default Value |
| --- | --- |
| logLevel | info |
| Logger.Filename | ``/var/log/cni-log.log`` |
| LogOptions.MaxSize | 100 |
| LogOptions.MaxAge | 5 |
| LogOptions.MaxBackups | 5 |
| LogOptions.Compress | true |
| LogOptions.Compress | true |
14 changes: 9 additions & 5 deletions logging.go
Original file line number Diff line number Diff line change
@@ -106,11 +106,7 @@ func init() {
SetLogFile(defaultLogFile)

// Create the default prefixer
defaultPrefix := &defaultPrefixer{
prefixFormat: "%s [%s] ",
timeFormat: defaultTimestampFormat,
}
SetPrefixer(defaultPrefix)
SetDefaultPrefixer()
}

func (p *defaultPrefixer) CreatePrefix(loggingLevel Level) string {
@@ -121,6 +117,14 @@ func SetPrefixer(p Prefixer) {
prefixer = p
}

func SetDefaultPrefixer() {
defaultPrefix := &defaultPrefixer{
prefixFormat: "%s [%s] ",
timeFormat: defaultTimestampFormat,
}
SetPrefixer(defaultPrefix)
}

// Set the logging options (LogOptions)
func SetLogOptions(options *LogOptions) {
// give some default value
30 changes: 24 additions & 6 deletions logging_test.go
Original file line number Diff line number Diff line change
@@ -4,7 +4,6 @@ import (
"bytes"
"fmt"
"io"
"io/ioutil"
"os"
"strings"
"testing"
@@ -207,7 +206,7 @@ var _ = Describe("CNI Logging Operations", func() {
AfterEach(func() {
// Clear contents of file
data := []byte("")
err := ioutil.WriteFile(logFile, data, 0)
err := os.WriteFile(logFile, data, 0)
Expect(err).ToNot(HaveOccurred())
})

@@ -276,7 +275,7 @@ var _ = Describe("CNI Logging Operations", func() {
AfterEach(func() {
// Clear contents of file
data := []byte("")
err := ioutil.WriteFile(logFile, data, 0)
err := os.WriteFile(logFile, data, 0)
Expect(err).ToNot(HaveOccurred())
})

@@ -421,7 +420,7 @@ var _ = Describe("CNI Logging Operations", func() {
AfterEach(func() {
// Clear contents of file
data := []byte("")
err := ioutil.WriteFile(logFile, data, 0)
err := os.WriteFile(logFile, data, 0)
Expect(err).ToNot(HaveOccurred())
})

@@ -448,6 +447,25 @@ var _ = Describe("CNI Logging Operations", func() {
})
})

When("prefix is set back to default", func() {

BeforeEach(func() {
SetDefaultPrefixer()
expectedPrefix = fmt.Sprintf("%s [%s] ", time.Now().Format(defaultTimestampFormat), InfoLevel)
})

It("sets the default prefix when logging to standard output", func() {
SetLogStderr(true)
out := captureStdErrLogging(validateLogFilePrefix, logFile, expectedPrefix)
Expect(out).To(ContainSubstring(expectedPrefix))
})

It("sets the default prefix when logging to the log file", func() {
Expect(validateLogFilePrefix(logFile, expectedPrefix)).To(BeTrue())
})

})

When("a custom prefix is provided", func() {

BeforeEach(func() {
@@ -481,7 +499,7 @@ func validateLogFilePrefix(filename string, prefix string) bool {
Infof(infoMsg)

// Read in contents of file
contents, err := ioutil.ReadFile(filename)
contents, err := os.ReadFile(filename)
if err != nil {
panic(err)
}
@@ -505,7 +523,7 @@ func validateLogFile(logLevel string, filename string) bool {
Verbosef(verboseMsg)

// Read in the log file
contents, err := ioutil.ReadFile(filename)
contents, err := os.ReadFile(filename)
if err != nil {
panic(err)
}