GithubHelp home page GithubHelp logo

Decide on a logging package about elbow HOT 20 CLOSED

atc0005 avatar atc0005 commented on August 29, 2024
Decide on a logging package

from elbow.

Comments (20)

atc0005 avatar atc0005 commented on August 29, 2024 1
package main

import (
	"flag"
	"fmt"
	"os"
)

func main() {
	required := []string{"b", "s"}
	os.Setenv("ENV_B", "test")
	flag.String("b", os.Getenv("ENV_B"), "b value")
	flag.Parse()

	seen := make(map[string]bool)
	flag.VisitAll(func(f *flag.Flag) {
		if f.Value.String() != "" {
			seen[f.Name] = true
		}
	})
	for _, req := range required {
		if !seen[req] {
			// or possibly use `log.Fatalf` instead of:
			fmt.Fprintf(os.Stderr, "missing required -%s argument/flag\n", req)
			os.Exit(2) // the same exit code flag.Parse uses
		}
	}
}

Idea for validating that non-empty values have been provided for ALL command-line flags (using the stdlib flag package).

from elbow.

atc0005 avatar atc0005 commented on August 29, 2024

Some of the packages I hope to evaluate (and or look further into):


from elbow.

atc0005 avatar atc0005 commented on August 29, 2024

sirupsen/logrus and goinggo/tracelog are both very appealing, the former more so because it is actively maintained and likely has sufficient features to cover all of my use cases.

from elbow.

atc0005 avatar atc0005 commented on August 29, 2024

This one looked good, but based on issues and pull requests it looks to be abandoned:

https://github.com/op/go-logging

from elbow.

atc0005 avatar atc0005 commented on August 29, 2024

https://godoc.org/github.com/inconshreveable/log15#hdr-Library_Use

log15 is intended to be useful for library authors as a way to provide configurable logging to users of their library. Best practice for use in a library is to always disable all output for your logger by default and to provide a public Logger instance that consumers of your library can configure. Like so:

package yourlib

import "github.com/inconshreveable/log15"

var Log = log.New()

func init() {
    Log.SetHandler(log.DiscardHandler())
}

Users of your library may then enable it if they like:

import "github.com/inconshreveable/log15"
import "example.com/yourlib"

func main() {
    handler := // custom handler setup
    yourlib.Log.SetHandler(handler)
}

from elbow.

atc0005 avatar atc0005 commented on August 29, 2024

Worth noting: The inconshreveable/log15 package author used Sirupsen/logrus as an inspiration for their package design.

Unfortunately it doesn't look like the library is receiving active support (quite a few issues/pull requests languishing).

from elbow.

atc0005 avatar atc0005 commented on August 29, 2024

https://github.com/avelino/awesome-go#logging

Worth looking at later if sirupsen/logrus doesn't work out.

from elbow.

atc0005 avatar atc0005 commented on August 29, 2024

https://github.com/apsdehal/go-logger

The formatting options remind me of Python's logging module.

from elbow.

atc0005 avatar atc0005 commented on August 29, 2024

Next steps (to make it clearer to myself):

from elbow.

atc0005 avatar atc0005 commented on August 29, 2024

On a related note: does flaggy support limiting options for a flag parameter to a slice of options?

Ex: logging level

from elbow.

atc0005 avatar atc0005 commented on August 29, 2024

Had some initial stumbling blocks with getting logrus setup/working with the syslog hook, but this code seems to work as intended with v1.4.2 of logrus (the latest at this time of writing):

package main

import (
	"log/syslog"

	// Use `log` if we are going to override the default `log`, otherwise
	// import without an "override" if we want to use the `logrus` name.
	// https://godoc.org/github.com/sirupsen/logrus
	log "github.com/sirupsen/logrus"

	// Official examples use either `lSyslog` or `logrus_syslog`
	// https://godoc.org/github.com/sirupsen/logrus/hooks/syslog
	lSyslog "github.com/sirupsen/logrus/hooks/syslog"
  )

  func main() {
	// https://godoc.org/github.com/sirupsen/logrus#New
	// https://godoc.org/github.com/sirupsen/logrus#Logger
	//log       := logrus.New()
	hook, err := lSyslog.NewSyslogHook("", "", syslog.LOG_INFO, "")

	if err == nil {
		// https://github.com/sirupsen/logrus#hooks
		// https://github.com/sirupsen/logrus/blob/master/hooks/syslog/README.md
		// Seems to require `log.AddHook(hook)`` vs `log.Hooks.Add(hook)`
		log.AddHook(hook)
	}

	log.Info("A walrus appears")

	log.WithFields(log.Fields{
			"animal": "walrus",
			"size":   10,
	}).Info("A group of walrus emerges from the ocean")

	log.WithFields(log.Fields{
			"omg":    true,
			"number": 122,
	}).Warn("The group's number increased tremendously!")

	log.WithFields(log.Fields{
			"omg":    true,
			"number": 100,
	}).Fatal("The ice breaks!")
  }

I worked from the https://github.com/atc0005/go-logrustest repo to figure out the syntax. When I went back and fully read over the logrus README.md file, I found that most of my stumbling blocks had been covered (to some degree or another).

Yet another case where it is better to try and read the manual from front-to-back before beginning.

from elbow.

atc0005 avatar atc0005 commented on August 29, 2024

Some ideas regarding selection of log output based on current environment:

https://callistaenterprise.se/blogg/teknik/2017/08/02/go-blog-series-part10/

from elbow.

atc0005 avatar atc0005 commented on August 29, 2024

Scratch notes for validating whether a support logging format was chosen on the command-line:

https://github.com/jessevdk/go-flags/blob/c0795c8afcf41dd1d786bebce68636c199b3bb45/option.go#L251

	if len(option.Choices) != 0 {
		found := false

		for _, choice := range option.Choices {
			if choice == *value {
				found = true
				break
			}
		}

		if !found {
			allowed := strings.Join(option.Choices[0:len(option.Choices)-1], ", ")

			if len(option.Choices) > 1 {
				allowed += " or " + option.Choices[len(option.Choices)-1]
			}

			return newErrorf(ErrInvalidChoice,
				"Invalid value `%s' for option `%s'. Allowed values are: %s",
				*value, option, allowed)
		}
	}

This existing function is probably a better fit for the current state of the code however:

func inFileExtensionsPatterns(ext string, exts []string) bool {

from elbow.

atc0005 avatar atc0005 commented on August 29, 2024

On a related note: does flaggy support limiting options for a flag parameter to a slice of options?

Ex: logging level

I didn't spot the option when I looked. The only flag package which seemed to do so was jessevdk/go-flags:

https://github.com/jessevdk/go-flags#example

var opts struct {
	// Slice of bool will append 'true' each time the option
	// is encountered (can be set multiple times, like -vvv)
	Verbose []bool `short:"v" long:"verbose" description:"Show verbose debug information"`

	// Example of automatic marshalling to desired type (uint)
	Offset uint `long:"offset" description:"Offset"`

	// Example of a callback, called each time the option is found.
	Call func(string) `short:"c" description:"Call phone number"`

	// Example of a required flag
	Name string `short:"n" long:"name" description:"A name" required:"true"`

	// Example of a flag restricted to a pre-defined set of strings
	Animal string `long:"animal" choice:"cat" choice:"dog"`

	// Example of a value name
	File string `short:"f" long:"file" description:"A file" value-name:"FILE"`

	// Example of a pointer
	Ptr *int `short:"p" description:"A pointer to an integer"`

	// Example of a slice of strings
	StringSlice []string `short:"s" description:"A slice of strings"`

	// Example of a slice of pointers
	PtrSlice []*string `long:"ptrslice" description:"A slice of pointers to string"`

	// Example of a map
	IntMap map[string]int `long:"intmap" description:"A map from string to int"`
}

from elbow.

atc0005 avatar atc0005 commented on August 29, 2024

Need to pick back up converting the other files in the project to using logrus-based log calls.

from elbow.

atc0005 avatar atc0005 commented on August 29, 2024

TODO: Need to move file-based logging into main() ?

https://stackoverflow.com/questions/32619318/logging-to-a-file-in-golang

from elbow.

atc0005 avatar atc0005 commented on August 29, 2024

Additional info:

from elbow.

atc0005 avatar atc0005 commented on August 29, 2024

TODO: Need to move file-based logging into main() ?

https://stackoverflow.com/questions/32619318/logging-to-a-file-in-golang

Some good ideas here:

https://stackoverflow.com/a/43827612/903870

The use of the sync package, the clean wrapper are both good. I don't see a Close() call however.

from elbow.

atc0005 avatar atc0005 commented on August 29, 2024

For now, I'm bundling a copy of *os.File with the Config object and checking for nil value to determine whether I've set something. Feels crude, broken somehow, but I can revisit this later once I learn more.

from elbow.

atc0005 avatar atc0005 commented on August 29, 2024

Going to go with logrus for this project. I can pick another package for the next project in order to get some experience with several different ones.

Will use the use-go-flags-and-logrus branch to complete the work for this issue.

from elbow.

Related Issues (20)

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.