Code Monkey home page Code Monkey logo

noodlog's Introduction

Noodlog

License Mentioned in Awesome Go CodeFactor Go Report Card Maintenance made-with-Go codecov Open Source Love svg1

alt text

Summary

Noodlog is a Golang JSON parametrized and highly configurable logging library.

It allows you to:

  • print go structs as JSON messages;
  • print JSON strings and raw strings messages as pure JSONs;
  • obscure some sensitive params from your logging;
  • chain objects or strings in your logs;
  • apply string templates to your logs;
  • choose to trace the caller file and function and fine tune the settings;
  • apply pretty printing or not;
  • apply colors to your logging;
  • customize colors per log level.

Import

go get github.com/gyozatech/noodlog

Usage

Let's assume you have Go 1.16+ istalled on your computer. Execute the following:

$ mkdir example && cd example
$ go mod init example
$ go get github.com/gyozatech/noodlog
$ touch main.go

Open main.go and paste the following code:

package main

import (
    "github.com/gyozatech/noodlog"
)

var log *noodlog.Logger

func init() {
   log = noodlog.NewLogger().SetConfigs(
      noodlog.Configs{
         LogLevel: noodlog.LevelTrace,
         JSONPrettyPrint: noodlog.Enable,
         TraceCaller: noodlog.Enable,
         Colors: noodlog.Enable,
         CustomColors: &noodlog.CustomColors{ Trace: noodlog.Cyan },
         ObscureSensitiveData: noodlog.Enable,
         SensitiveParams: []string{"password"},
      },
    )
}

func main() {
    // simple string message (with custom color)
    log.Trace("Hello world!")
    
    // chaining elements
    log.Info("You've reached", 3, "login attemps")
    
    // using string formatting
    log.Warn("You have %d attempts left", 2)
    
    // logging a struct with a JSON
    log.Error(struct{Code int; Error string}{500, "Generic Error"})
    
    // logging a raw JSON string with a JSON (with obscuring "password")
    log.Info(`{"username": "gyozatech", "password": "Gy0zApAssw0rd"}`)
    
    // logging a JSON string with a JSON (with obscuring "password")
    log.Info("{\"username\": \"nooduser\", \"password\": \"N0oDPasSw0rD\"}")
}

Running this example with:

$ go run main.go

You'll get the following output:

alt text

Settings

Noodlog allows you to customize the logs through various settings. You can use various facility functions or the SetConfigs function which wraps all the configs together.


LogLevel

To set the logging level, after importing the library with:

import (
    "github.com/gyozatech/noodlog"
)

var log *noodlog.Logger

func init() {
   log = noodlog.NewLogger()
}

you can use the facility method:

log.LogLevel("warn")

or the SetConfigs function:

log.SetConfigs(
    noodlog.Configs{
        LogLevel: noodlog.LevelWarn,
    },
)

log.LevelWarn is a pre-built pointer to the string "warn".

The default log level is info.


JSON Pretty Printing

After importing the library with:

import (
    "github.com/gyozatech/noodlog"
)

var log *noodlog.Logger

func init() {
   log = noodlog.NewLogger()
}

To enable pretty printing of the JSON logs you can use:

log.EnableJSONPrettyPrint()

or

log.SetConfigs(
    noodlog.Configs{
       JSONPrettyPrint: noodlog.Enable,
    },
)

noodlog.Enable is a pre-built pointer to the bool true.

to disable pretty printing you can use:

log.DisableJSONPrettyPrint()

or

log.SetConfigs(
    noodlog.Configs{
       JSONPrettyPrint: noodlog.Disable,
    },
)

noodlog.Disable is a pre-built pointer to the bool false.

The default value is false.


Colors

After importing the library with:

import (
    "github.com/gyozatech/noodlog"
)

var log *noodlog.Logger

func init() {
   log = noodlog.NewLogger()
}

to enable colors in JSON logs you can use:

log.EnableColors()

or

log.SetConfigs(
    noodlog.Configs{
        Colors: noodlog.Enable,
    },
)

noodlog.Enable is a pre-built pointer to the bool true.

To disable colors you can use:

log.DisableColors()

or

log.SetConfigs(
    noodlog.Configs{
        Colors: noodlog.Disable,
    },
)

noodlog.Disable is a pre-built pointer to the bool false.

The default value is false.

Color

The basic way to use a custom color is declaring using a pointer of a string representing the color.
log.Cyan, log.Green, log.Default, log.Yellow, log.Purple, log.Red, log.Blue are pre-build pointers to the strings "cyan", "green", "default", "yellow", "purple", "red", "blue".

For instance, you can customize trace color by:

log.SetTraceColor(noodlog.Cyan)

A more detailed explanation of each log level is available later into this section.

Composition of a color

Color can be composed with text color and background color. For each level it can be composed using a string or a true color notation.

Trivial usage is creating a new color like:

log.NewColor(noodlog.Red)

It results a red text on default background

Adding a background color can be done through:

log.NewColor(noodlog.Red).Background(noodlog.Cyan)

In this scenario it prints red text on cyan background

A third option is to edit just background color using default text color:

log.Background(noodlog.Cyan)

A list of pre-built pointer of a string is [here](#Composition of a color).

Library provides also more customization through the usage of true color notation (RGB value). Before the usage of this notation, please consider if your terminal supports truecolor. For instance if you execute (printf required):

printf '\033[38;2;255;0;0mHello World\033[0m'

a red text "Hello World" should be displayed on the screen

In this way a wider set of color is available for logging, besides of the previous way it can be created a color as:

log.NewColorRGB(255,0,0).BackgroundRGB(0,0,255)

Where a red text (255 for red, 0 the others) is showed on blue background (255 for blue, 0 for others).

As in the previous scenario, NewColorRGB and BackgroundRGB hasn't to be executed combined.

Color can be used to set color of Trace log, by typing:

log.SetTraceColor(noodlog.NewColorRGB(255,0,0).BackgroundRGB(0,0,255))

You can customize the single colors (for log level) by using:

log.SetTraceColor(noodlog.Cyan)
log.SetDebugColor(noodlog.NewColorRGB(255,255,0))
log.SetInfoColor(noodlog.NewColor(noodlog.Red).Background(noodlog.Cyan))
log.SetWarnColor(noodlog.NewColor(noodlog.Green).BackgroundRGB(0,255,255))
log.SetErrorColor(noodlog.NewColorRGB(128,255,0).Background(noodlog.Purple))

or

log.SetConfigs(
    noodlog.Configs{
        Colors: noodlog.Enable,
        CustomColors: &noodlog.CustomColors{ 
            Trace: noodlog.Cyan, 
            Debug: noodlog.NewColorRGB(255,255,0),
            Info:  noodlog.NewColor(noodlog.Red).Background(noodlog.Cyan),
            Warn:  noodlog.NewColor(noodlog.Green).BackgroundRGB(0,255,255),
            Error: noodlog.NewColorRGB(128,255,0).Background(noodlog.Purple),    
        },
    },
)

Here we highlight all the different combination available to customize colors.

When enabled, the default colors are:

  • trace: "default"
  • info: "default"
  • debug: "green"
  • warn: "yellow"
  • error: "red"

Trace the caller

Noodles allows you to print the file and the function which are calling the log functions.

After importing the library with:

import (
    "github.com/gyozatech/noodlog"
)

var log *noodlog.Logger

func init() {
   log = noodlog.NewLogger()
}

to enable the trace caller you can use:

log.EnableTraceCaller()

or

log.SetConfigs(
    noodlog.Configs{
        TraceCaller: noodlog.Enable,
    },
)

noodlog.Enable is a pre-built pointer to the bool true.

To disable it:

log.DisableTraceCaller()

or

log.SetConfigs(
    noodlog.Configs{
        TraceCaller: noodlog.Disable,
    },
)

noodlog.Disable is a pre-built pointer to the bool false.

The default value is false.

Important: if you want to import noodlog only in one package of your project (in order to configure it once) and wraps the logging functions you can use the EnableSinglePointTracing to trace file and function the real caller and not of your logging package.

For example:

main.go

package main

import (
   log "example/logging"
)

func main() {
   // main.main real caller we want to track 
   log.Info("Hello folks!")
}

logging/logger.go

package logging

import (
    "github.com/gyozatech/noodlog"
)

var l *noodlog.Logger

func init() {
    l = noodlog.NewLogger()
    // configure logger once
    l.SetConfig(
        noodlog.Configs{
         TraceCaller: noodlog.Enable,
         SinglePointTracing: noodlog.Enable,
      },
    )
}

// wrapper function
func Info(message ...interface{}) {
    // if we wouldn't enable SinglePointTracing
    // logger.Info would have been considered the caller to be tracked
    l.Info(message...)
}

Sensitive params

Noodlog gives you the possibility to enable the obscuration of sensitive params when recognized in the JSON structures (not in the simple strings that you compose).

After importing the library with:

import (
    "github.com/gyozatech/noodlog"
)

var log *noodlog.Logger

func init() {
   log = noodlog.NewLogger()
}

You can enable the sensitive params obscuration with the facility methods:

log.EnableObscureSensitiveData([]string{"param1", "param2", "param3"})

or with the SetConfig function:

log.SetConfigs(
    noodlog.Configs{
        ObscureSensitiveData: noodlog.Enable,
        SensitiveParams: []string{"param1", "param2", "param3"},
    },
)

Where noodlog.Enable is a pre-built pointer to the bool true.

To disable the sensitive params obscuration you can set:

log.DisableObscureSensitiveData()

or

log.SetConfigs(
    noodlog.Configs{
        ObscureSensitiveData: noodlog.Disable,
    },
)

Where noodlog.Disable is a pre-built pointer to the bool false.

The default value for the obscuration is false.


Contribute to the project

If you want to contribute to the project follow the following guidelines. Any form of contribution is encouraged!

noodlog's People

Contributors

alessandroargentieri avatar amoghrajesh avatar davideimola avatar ilmanzo avatar marcosansoni avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

noodlog's Issues

Refactor logger as struct

User Story

As a user, I would like to create an instance of my logger to prevent using a global set of functions.

Detailed Description

By having a logger with a set of global functions and settings we can have concurrency issues, mostly in tests.

Create a struct Logger and move all the configs and behaviors on this object.
Also, tests and documentation must be updated after this deep refactor.

Include examples of "out of the box" logs format in the README

Currently, in the README is possible to see an example of a colorized pretty-printed output.
This is very cool, although it would be useful for someone stumbling upon this library knowing what's the default behavior without any of the configured parameters.

Sometimes it's useful to print everything on a single line and let the use possibly format the output, and some people would look for that specific feature first

Good stuff! ๐Ÿ‘

Test TestSimpleLogger is flaky

Bug description

The test TestSimpleLogger is a bit flaky. We must resolve the flakiness.

How to reproduce

Run the tests without cache and you can see the test can go both green and red.

Color enhancements

User Story

As a developer, I would like to make some enhancements to Colors.

Detailed Description

The proposed enhancements are as follows:

  • move Color struct and its methods to log_struct.go file where all the structs of the library are contained. (Even if it's very contextual to have it in color.go file)
  • if Color struct and its attribute Code are only reachable from the internal of the noodlog package, change to lowercase letters (color, code). If only Code can be private, it would be the only one to be changed lowercase.
  • if we can use a default code color, change the color.code from pointer to string. This way we can avoid using the function ToCode() in order to get its string value, but we can access directly with color.code instead of color.ToCode(). If it's not possible to remove the pointer and to delete ToCode() function, evaluate if it's possible to use lowercase toCode().

Add badges to readme

We want to have badges in the README.md file through the github actions.
Some interesting badges could be:

  • build
  • test coverage
  • static code analysis analysis

Logs don't go new line

Bug description

The log messages don't go to next line.

How to reproduce

Just check the logged messages

Environment

  • Go version 16+
  • OS and Architecture: any

Anything else

Hint: change the fmt.Fprintf() function into fmt.Fprintln() into logger.go -> printLog function.

Extend sensitive data obfuscation

The regex used to obfuscate sensitive data nowadays works only on string parameters.
Extend the regex or add a new regex in order to get also data without double-quotes.
In that case, try to figure out if null is a better value for boolean, numbers in place of "**************" used for strings.

Add the possibility to print log in files

User Story

As a developer, I would like to have the possibility to choose to redirect all logs in a file (one file for the day) in place of standard output.

Detailed Description
Add a setting to define filename, log rotation, etc. and switch the logic when needed.

Add the Code Coverage

User Story

As a developer, I would like to have code coverage for this project.

Detailed Description

Adds codecov for this project.

extract ObscureSensitiveParams function

Now you can enable or disable the ObscureSensitiveData functionality whose check is applied to all log records when enabled.
It slows down the execution time even when you log a simple record.
Extract and make ObscureSensitiveParam public, in order to give the possibility to choose to disable the functionality and using it only when needed.
This could be done this way:

log.SetConfig{ &log.Configs{
         ObscureSensitiveData: log.Disable,
         SensitiveParams: []string{"password"},
     }
}

And then:

log.Info(log.ObscureSensitiveData(myrecord))

This way the feature remains disabled by default but used only when needed.

Create Benchmark

User Story

As a developer, I would like to have a benchmark for noodlog performances.

Detailed Description

It's also possible to compare noodlog with logrus, because it solves similar problems and has similar performances.

Anything else

Keep in mind that enabling sensitive data obscuration, colors, pretty printing is more cost computational than not using these confs.

Keep also in mind that printing a JSON or an Object is more cost computational that writing a simple string record.

Enable Datetime format customization

User Story

As an operator, I would like to get a DateTime formatted according to my needs.

Detailed Description

Maintain the present formatting as default and allow user customization in order to vary the format, consider the timezone too.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.